PostgreSQL同一查询在不同前端工具的性能差异及执行策略决策方疑问
首先直接给结论:查询的执行计划(包括是否启用并行)最终是由PostgreSQL服务器决定的,但客户端工具可能通过悄悄修改会话级参数、调整查询发送方式,间接影响服务器的决策逻辑。结合你遇到的场景,我来拆解具体原因:
你的场景复盘
你使用的是PostgreSQL 11.5,服务器配置了max_parallel_workers = 8、max_parallel_workers_per_gather = 4,但不同客户端执行同一查询select column_1, count(1) from table group by 1 order by 1 desc时结果差异极大:
- pgAdmin3 LTS 1.23:4线程并行执行,耗时12秒
- DbVisualizer 10.0.21:默认执行单线程跑,耗时70秒;但用
EXPLAIN ANALYZE时却会用并行 - Navicat:4线程并行,耗时30秒
核心原因分析
1. 服务器才是执行计划的决策者,但客户端能"干扰"参数
PostgreSQL服务器生成执行计划时,会参考全局配置、会话级参数、表统计信息、查询复杂度等。客户端本身不能强制服务器用单线程,但很多工具会在建立连接时自动设置一些会话级参数,这些参数可能直接关掉了并行功能。
2. DbVisualizer的特殊情况:普通查询被改了参数
你提到DbVisualizer直接执行不并行,但EXPLAIN ANALYZE却正常并行,这几乎可以肯定是工具在执行普通查询时,偷偷修改了并行相关的会话参数,比如:
- 自动执行了
SET max_parallel_workers_per_gather = 0;(直接禁用并行聚集) - 或者关闭了
enable_parallel_hash、enable_parallel_gather这类并行开关 - 还有可能是工具开启了某种"兼容模式"或者"查询优化"选项,导致服务器认为不需要并行
3. Navicat和pgAdmin的耗时差异:客户端处理开销
Navicat虽然和pgAdmin用了相同的并行线程数,但耗时更长,这是因为并行执行是服务器端的行为,客户端只负责接收和处理结果。不同工具的结果集解析、UI渲染效率不同,会导致最终的总耗时有差异,但服务器端的执行速度其实是差不多的。
验证和解决方法
如果你想确认DbVisualizer的问题,可以做这几步:
- 在DbVisualizer中,先执行
SHOW max_parallel_workers_per_gather;和SHOW enable_parallel_gather;,看看会话级参数是不是被改成了0或者off - 手动设置参数后再执行查询:
如果这时候能并行,就坐实了是工具修改参数的问题SET max_parallel_workers_per_gather = 4; select column_1, count(1) from table group by 1 order by 1 desc; - 检查DbVisualizer的连接配置,看看有没有"禁用并行"、"兼容旧版本"这类隐藏选项
总结
不要被现象迷惑:服务器始终是执行计划的最终决策者,但客户端工具可能通过会话参数、连接选项间接影响这个决策。你遇到的DbVisualizer问题,大概率是工具的默认配置悄悄修改了并行相关参数,导致服务器选择了单线程执行计划。
内容的提问来源于stack exchange,提问作者Baker

