PostgreSQL/并行查询
外观
从 9.6 版本开始,PostgreSQL 支持并行处理查询。在当今大多数服务器中,存在大量的 CPU。并发使用这些 CPU 可以显著缩短查询的执行时间。因此,查询优化器会尝试创建计划,以便为每个查询执行多个进程。在运行时,这些进程会以协调的方式在共享缓冲区的不同部分并行工作。
并行执行由执行计划中的“收集节点”发起。当在运行时到达这些节点时,实际运行的进程会请求计划中指定的额外进程数量(“后台工作进程”)。原始进程加上额外进程会并行执行计划中的子节点。“收集节点”还有另外一项任务,即收集和累积其子进程的结果。
此功能并非在所有情况下都使用。这来自三个不同的影响:查询类型、PostgreSQL 参数设置以及实际的实现。
- 如果查询会导致执行计划高度依赖 I/O,那么并行化带来的好处并不大,因为并行化是一种 RAM 访问功能。相比之下,需要高 CPU 活动的查询(例如:... where text like '%xyz%';没有相应的索引)将从并行化中获益更多。因此,并行化更有可能被选择用于第二种类型的查询。
- PostgreSQL 的默认行为(在 9.6 版本中)是使用传统行为,即只调用单个进程。如果想要使用并行化功能,则必须设置一些参数:
max_parallel_workers_per_gather
定义了允许与每个“收集节点”并行运行的进程的最大数量。由于默认值为0
,因此会导致使用传统行为,除非更改此值。如上所述,每个与“收集节点”并行工作的进程都会在“后台工作进程”中实现。每个实例中“后台工作进程”的总数受max_worker_processes
限制,默认值为8
。因此,可能需要增加该值。此外,参数dynamic_shared_memory_type
必须设置为除none
以外的值。 - 9.6 版本的实际实现包含许多限制,这些限制源于必须确保此基本实现能够在所有环境中稳定运行。在未来的版本中,其中一些限制可能会被消除。
- 它仅限于纯只读命令:不包括 UPDATE、DELETE,也不包括任何写入命令的 CTE 部分。
- 如果涉及任何行的锁。
- 如果事务隔离级别为
serializable
。 - 如果查询在另一个已并行化的查询中运行。例如,如果由并行查询调用的函数本身发出 SQL 查询。