当前位置: 首页 > news >正文

PostgreSQL选Join策略有啥小九九?Nested Loop/Merge/Hash谁是它的菜?


url: /posts/2eca89463454fd4250d7b66243b9fe5a/
title: PostgreSQL选Join策略有啥小九九?Nested Loop/Merge/Hash谁是它的菜?
date: 2025-10-10T03:10:41+08:00
lastmod: 2025-10-10T03:10:41+08:00
author: cmdragon

summary:
PostgreSQL中的连接查询(JOIN)通过查询优化器选择成本最低的执行策略,主要包含三种Join策略:Nested Loop Join、Merge Join和Hash Join。Nested Loop Join适用于小表或内层表有索引的场景;Merge Join适合两个表Join键都有有序索引的情况;Hash Join则用于大表与小表的连接,通过构建Hash表加速查询。优化器还会根据表大小和索引情况选择Join顺序,优先减少中间结果的大小。

categories:

  • postgresql

tags:

  • 基础入门
    • PostgreSQL
  • 连接查询
  • Join策略
  • Nested Loop Join
  • Merge Join
  • Hash Join
  • 查询优化器

cmdragon_cn.png

扫描二维码关注或者微信搜一搜:编程智域 前端至全栈交流与成长

发现1000+提升效率与开发的AI工具和实用程序:https://tools.cmdragon.cn/

一、连接查询的核心逻辑:PostgreSQL如何选择Join策略

在PostgreSQL中,连接查询(JOIN)的本质是将多个表的行根据指定条件组合成新的结果集。比如查询“每个用户的订单信息”,需要将users表和orders表通过user_id字段连接。但同样的查询可以有多种执行方式,PostgreSQL的查询优化器(Optimizer)会根据表的大小、索引情况、数据分布等因素,选择“预计成本最低”的执行策略——这就是Join策略的选择过程。

根据官方文档,优化器的工作流程大概分为两步:

  1. 单表扫描计划生成:为每个涉及的表生成可能的扫描计划(比如 sequential scan 全表扫描、index scan 索引扫描)。
  2. Join策略选择:针对多表连接,从三种基础策略(Nested Loop Join、Merge Join、Hash Join)中选择最优方案,并确定Join的顺序。

接下来,我们逐个拆解这三种Join策略,理解它们的原理、适用场景和优化技巧。

二、Nested Loop Join:最“直观”的连接方式

2.1 原理:外层循环驱动内层查询

Nested Loop Join(嵌套循环连接)是最基础的Join策略,逻辑类似于编程语言中的“双重循环”:

  • 外层表(Left Relation):作为“驱动表”,每次取一行数据;
  • 内层表(Right Relation):对于外层表的每一行,用该行的Join键去查询内层表的匹配行;
  • 输出结果:将匹配的行组合后返回。

用伪代码表示:

for left_row in left_table:for right_row in right_table where right_row.key == left_row.key:output (left_row, right_row)

但直接这样写效率极低——如果内层表是全表扫描,外层有1000行,内层就要扫1000次!PostgreSQL的优化点在于:如果内层表的Join键上有索引,那么内层查询会变成快速的索引查找(比如B-tree索引的index scan),从而将内层的时间复杂度从O(N)降到O(log N)。

2.2 流程图:带索引的Nested Loop Join

外层循环(左表行)│▼
取出左表行的Join键(如user_id=123)│▼
内层查询:用Join键查右表的索引(如orders.user_id索引)│▼
找到右表中匹配的行(如orders where user_id=123)│▼
组合左表行和右表行,输出结果

2.3 示例:带索引的Nested Loop Join

假设我们有两个表:

  • users(用户表):user_id(主键,B-tree索引)、name(1000行);
  • orders(订单表):order_id(主键)、user_id(B-tree索引)、amount(10000行)。

查询“所有用户的订单信息”:

-- 示例1:Nested Loop Join(PostgreSQL会自动选择)
SELECT u.name, o.order_id, o.amount
FROM users u
JOIN orders o ON u.user_id = o.user_id;

执行计划分析(用EXPLAIN ANALYZE查看):

Nested Loop Join  (cost=0.29..115.32 rows=1000 width=44) (actual time=0.03..1.23 rows=1000 loops=1)->  Seq Scan on users u  (cost=0.00..22.00 rows=1000 width=36) (actual time=0.01..0.21 rows=1000 loops=1)->  Index Scan using orders_user_id_idx on orders o  (cost=0.29..0.09 rows=1 width=16) (actual time=0.00..0.00 rows=1 loops=1000)Index Cond: (user_id = u.user_id)
  • 外层是users表的全表扫描(Seq Scan);
  • 内层是orders表的user_id索引扫描(Index Scan),每次用u.user_id作为条件;
  • 总时间仅1.23毫秒,因为内层的索引扫描非常快。

2.4 适用场景

Nested Loop Join最适合

  • 外层表(左表)很小,或者内层表的Join键上有高效索引
  • 需要“尽早返回结果”的场景(比如OLTP系统中的点查询)。

反例:如果内层表没有索引,且数据量大,Nested Loop会变成“灾难”——比如外层有100万行,内层全表扫描100万次,时间会爆炸。

三、Merge Join:排序后的并行匹配

3.1 原理:先排序,再“双指针”扫描

Merge Join(合并连接)的核心思想是:将两个表的Join键排序后,用双指针并行扫描匹配。步骤如下:

  1. 排序阶段:将左表和右表按Join键排序(可以是显式的
http://www.dtcms.com/a/465036.html

相关文章:

  • 数据链路层协议之RSTP协议
  • 让AI说“人话“:TypeChat.NET如何用强类型驯服大语言模型的“野性“
  • .pth文件
  • 北京网站建设销售招聘宣传式网站
  • Navicat笔记之使用技巧
  • 第五天:自动化爬虫
  • 长春企业网站哪里做的好12306网站制作
  • Java学习之旅第二季-16:接口
  • 147、【OS】【Nuttx】【周边】效果呈现方案解析:$PATH 隔离
  • 前端笔试复盘 | 知识点总结
  • 哪个地区的网站建设最好免费发群二维码的网站
  • GitHub 热榜项目 - 日榜(2025-10-10)
  • MySQL聚合查询的进阶技巧用WITHROLLUP实现多维度数据汇总分析
  • 用 PyQt5 + FFmpeg 打造批量视频音频提取器
  • 华为 Mate80 要来了,或搭载最新麒麟芯片
  • Frida辅助分析OLLVM虚假控制流程(下)
  • MySQL(二) - 数据表管理
  • 商丘网站建设大全网站改版 大量旧页面
  • 简单网站编写
  • 用AI写的【实时文件搜索引擎】python源码【找资源】
  • 无为建设局网站深圳东门解封了吗
  • 【Linux】入门指南:基础指令详解Part Two
  • 如何下载 Git 仓库中的所有分支到本地并实现Python自动化操作
  • 掌握前后端数据交互的3种核心方式
  • 网络、主机安全扫描工具
  • 论文笔记 -《MUON IS SCALABLE FOR LLM TRAINING》
  • soular入门到实战(6) - soular+kanass+sward+postin实现sso单点登录
  • 建设农垦网站赣州网站制作
  • vue3 el-date-picker 日期选择器校验规则-选择日期范围不能超过七天
  • 【论文阅读】Debating with More Persuasive LLMs Leads to More Truthful Answers