首页/数据/SQL 速查/PG 连接节点:Nested Loop / Hash / Merge
性能与执行计划72 条

PG 连接节点:Nested Loop / Hash / Merge

计划树里三种连接算法各有适用场景:驱动集大小、内表索引、两侧有序性是选择依据。

SQL 速查数据更新于 2026-10-13

三种连接节点的选择依据

计划树里连接以三种形态出现:嵌套循环、哈希连接、归并连接。选择依据是驱动侧估算行数、内表连接列是否有索引、两侧数据是否已经有序。看计划时先判断节点类型,再判断它是否与实际数据规模相匹配:驱动侧只有几十行却选了哈希连接,或者驱动侧几万行却选了嵌套循环,都是明显的信号。

基本信息

适用平台PostgreSQL 12 及以上
嵌套循环驱动集小、内表连接列有索引时逐行查找
哈希连接等值连接且两侧数据量较大,构建哈希表后探测
归并连接两侧已按键有序(排序结果或索引输出)
并行执行计划里出现收集节点表示使用了并行工作进程

典型使用场景

  • 大表等值连接变慢:确认哈希连接是否因内存不足而分批落盘
  • 小结果集连接:确认走的是嵌套循环而不是笨重的哈希构建
  • 两表都很大且已排序:归并连接可能是最优选择
  • 评估并行度:看收集节点与计划工作进程数是否符合预期
  • 对比调整内存参数前后的节点变化

识别连接节点

识别连接节点
EXPLAIN
SELECT u.name, o.total
FROM users u
JOIN orders o ON o.user_id = u.id
WHERE u.city = 'shanghai';
-- 输出里可能出现哈希连接节点:
--   Hash Join  (cost=...)
--     Hash Cond: (o.user_id = u.id)

-- 嵌套循环:常见于驱动侧很小、内表连接列有索引的情况
-- 归并连接:两侧按键有序时出现

-- 需要真实行数与内存使用时用分析模式(会真实执行)
-- EXPLAIN (ANALYZE, BUFFERS) SELECT ... ;

-- 哈希表超出内存会分批落盘,输出中会给出批次与磁盘占用信息
-- 先按会话调整排序与哈希内存上限,验证后再决定是否落到实例配置

连接节点选择依据

节点类型适用场景异常信号
嵌套循环驱动集小、内表连接列有索引驱动集很大且内表无索引
哈希连接等值连接、两侧数据量较大哈希批次很多、磁盘占用大
归并连接两侧已按键有序为它额外排序付出高代价
并行收集节点大表扫描与聚合工作进程数远超预期占用资源
物化节点中间结果需要重用物化行数远超估算
哈希连接本身没有好坏之分:它在数据量大时通常是对的选择,真正的问题往往是内存上限偏小,导致哈希表分批落盘。先看输出里的批次与磁盘占用,再决定是否调内存。
并行执行会放大资源占用:并发请求多时,每条语句的并行工作进程叠加起来可能吃满 CPU。评估并行度要看实例的整体并发,不只盯单条语句的耗时。

易错点

  • 把嵌套循环一律当低效:驱动集小且内表有索引时它就是最优解,盲目干预反而更慢
  • 只盯连接算法不调内存参数:哈希分批落盘时最直接的收益来自内存上限
  • 看到并行度提高就以为变快:并发高时并行进程互相抢占 CPU,整体吞吐可能下降
  • 用计划成本估算判断节点好坏,不看真实行数与内存使用,结论与实际相反
  • 在生产直接跑分析模式:语句被真实执行,写操作会造成数据变更

数据来源与参考

  • PostgreSQL Documentation §14.1 Using EXPLAIN
  • PostgreSQL Documentation §15.5 Planner Method Configuration
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌