Table of Contents
PostgreSQL 可以制定能够利用多个 CPU、从而更快回答查询的查询计划。这一特性称为并行查询。许多查询无法从并行查询中获益,要么是因为当前实现存在限制,要么是因为根本不存在比串行查询计划更快的可行计划。不过,对于能够从中受益的查询,并行查询带来的加速通常非常明显。许多查询在使用并行查询时可以获得两倍以上的速度提升,有些甚至可以达到四倍或更高。那些访问大量数据但只向用户返回少量行的查询,通常最能从并行查询中获益。本章将解释并行查询的工作方式以及可以在哪些情况下使用它,从而帮助希望利用这一特性的用户了解可以期待的效果。
当优化器确定并行查询是某个特定查询最快的执行策略时,它会创建一个包含 Gather 或 Gather Merge 节点的查询计划。下面是一个简单示例:
EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
QUERY PLAN
-------------------------------------------------------------------------------------
Gather (cost=1000.00..217018.43 rows=1 width=97)
Workers Planned: 2
-> Parallel Seq Scan on pgbench_accounts (cost=0.00..216018.33 rows=1 width=97)
Filter: (filler ~~ '%x%'::text)
(4 rows)
无论在哪种情况下,Gather 或 Gather Merge 节点都恰好有一个子计划,也就是将以并行方式执行的那部分计划。如果 Gather 或 Gather Merge 节点位于计划树的最顶端,那么整个查询都会并行执行;如果它位于计划树中的其他位置,那么只有它下方的那部分计划会并行运行。在上面的示例中,查询只访问一个表,因此除了 Gather 节点本身之外只有一个计划节点;由于该计划节点是 Gather 节点的子节点,所以它会并行运行。
通过 使用 EXPLAIN,你可以看到规划器选择的工作进程数量。当查询执行到 Gather 节点时,实现用户会话的进程会请求与规划器所选数量相同的后台工作进程。规划器会考虑使用的后台工作进程数量,最多不超过 max_parallel_workers_per_gather。任意时刻可存在的后台工作进程总数同时受到 max_worker_processes 和 max_parallel_workers 的限制。因此,并行查询实际运行时可能使用比计划更少的工作进程,甚至完全没有工作进程。最优计划可能依赖于可用工作进程的数量,因此这会导致查询性能不佳。如果这种情况经常发生,可以考虑增大 max_worker_processes 和 max_parallel_workers,让更多工作进程能够同时运行;或者降低 max_parallel_workers_per_gather,使规划器请求更少的工作进程。
为某个并行查询成功启动的每个后台工作进程都会执行计划的并行部分。领导者也会执行这部分计划,但它还承担着额外职责:必须读取所有由工作进程生成的元组。当计划的并行部分只生成少量元组时,领导者通常会表现得很像一个额外的工作进程,从而加快查询执行。反过来,当计划的并行部分生成大量元组时,领导者可能几乎完全忙于读取工作进程生成的元组,并执行位于 Gather 或 Gather Merge 节点之上的计划节点所要求的后续处理。在这种情况下,领导者实际参与执行计划并行部分的工作就会很少。
当计划并行部分的顶层节点是 Gather Merge 而不是 Gather 时,这表示每个执行计划并行部分的进程都会按排序顺序生成元组,而领导者会执行保持顺序的归并。相比之下,Gather 会以任意方便的顺序从工作进程读取元组,从而破坏原本可能存在的排序顺序。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。