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

PostgreSQL Merge Join 大白话详解

用生活中最直观的例子彻底搞懂 Merge Join 是什么、为什么快、什么时候用。一、先从生活场景开始场景一两摞乱序试卷找同学期末考试老师手里有两摞试卷A 摞数学试卷500 份乱序堆放B 摞语文试卷500 份乱序堆放现在要找出同一个同学的两份试卷配成一对。笨办法Nested Loop拿起数学试卷第1份张三→ 翻遍500份语文找张三 → 找到 拿起数学试卷第2份李四→ 翻遍500份语文找李四 → 找到 ... 总共翻了500 × 500 25万次聪明办法先排序再合并Merge Join第一步把两摞试卷都按学号排好序001~500 第二步左手拿A摞右手拿B摞同时从第一份开始翻 左手001号, 右手001号 → 匹配配成一对两手同时往后翻一张 左手002号, 右手003号 → 左边小只翻左手 左手003号, 右手003号 → 匹配两手同时往后翻一张 左手004号, 右手005号 → 左边小只翻左手 ... 总共翻了500 500 1000次结论排完序之后各翻一遍就结束两摞试卷绝不回头。二、Merge Join 核心原理双指针扫描Merge Join 本质是对两个有序序列用双指针做合并规则非常简单指针A → [1, 3, 5, 7, 9] 指针B → [2, 3, 6, 7, 8] 规则 A B → 匹配两指针同时右移 A B → A指针右移 A B → B指针右移 任意一方到头 → 结束逐步演示步骤1A1, B2 → 12A右移 步骤2A3, B2 → 32B右移 步骤3A3, B3 → 匹配✅ 双方右移 步骤4A5, B6 → 56A右移 步骤5A7, B6 → 76B右移 步骤6A7, B7 → 匹配✅ 双方右移 步骤7A9, B8 → 98B右移 步骤8A9, B结束 → 扫描结束 总步骤数8次远小于 5×525次两个序列各走一遍绝不回头这就是 O(NM) 的来源。三、时间复杂度分析3.1 有索引时O(N M)B-Tree 索引本身就是按 Key 排好序的有序结构。索引结构简化示意 key001 → 行指针 key002 → 行指针 key003 → 行指针 ...天然有序PostgreSQL 直接沿着两个索引做双指针扫描无需临时排序直接 O(NM)。3.2 无索引时O(N·logN M·logM)没有索引PostgreSQL 必须先把数据排序第一步对 N 行数据排序 → O(N·logN) 第二步对 M 行数据排序 → O(M·logM) 第三步双指针合并 → O(NM) 总计O(N·logN M·logM)举例N M 500万有索引500万 500万 1000万次操作 无索引500万×23 500万×23 1000万 ≈ 2.4亿次操作没有索引时代价远超 Hash Join规划器通常不会选 Merge Join。四、Merge Join vs Hash Join选哪个这是实际工作中最常见的疑问一张表说清楚对比项Hash JoinMerge Join需要排序❌ 不需要✅ 必须有序靠索引额外内存需要把小表装进 HashMap几乎为零只有两个指针有索引时不一定用索引直接复用索引O(NM)无索引时O(NM)照样快需先排序代价大内存不够时会写临时磁盘变慢不受内存限制规划器偏好通用首选有合适索引时才考虑一句话记忆没有索引 → Hash Join建字典O(NM) 有排序索引 → Merge Join双指针O(NM)且不占内存 内存紧张 → 优先 Merge Join不需要建 HashMap五、用 EXPLAIN 看规划器的选择EXPLAINANALYZESELECTa.orde_idFROMorders aJOINorders bONa.orde_idb.orde_idANDb.version_number20260522000707011WHEREa.version_number20260521172049432;执行计划输出示例-- 没有索引时规划器选 Hash Join Hash Join (cost...) Hash Cond: (a.orde_id b.orde_id) - Seq Scan on orders a (...) ← 全表扫描 - Hash - Seq Scan on orders b (...) ← 建 HashMap -- 有 (version_number, orde_id) 联合索引时规划器可能选 Merge Join Merge Join (cost...) Merge Cond: (a.orde_id b.orde_id) - Index Scan using idx_a on orders a (...) ← 走索引已有序 - Index Scan using idx_b on orders b (...) ← 走索引已有序看到Merge JoinIndex Scan的组合说明规划器充分利用了索引的有序性。六、什么情况下 Merge Join 会失效6.1 Join Key 数据类型不一致-- a.id 是 INTb.id 是 VARCHARONa.idb.id-- 需要隐式类型转换破坏有序性无法 Merge Join6.2 索引列被函数包裹ONLOWER(a.name)LOWER(b.name)-- 走不了索引无法 Merge Join6.3 非等值 JoinONa.priceb.price-- Merge Join 只支持等值连接6.4 数据分布极度不均匀某个 Key 值有几百万重复值低基数双指针在这个值上会反复扫描退化成 O(N×M)。七、总结Merge Join 的本质两个有序序列 双指针 各走一遍O(NM)什么时候 Merge Join 最好用✅ Join Key 上双方都有 B-Tree 索引 ✅ 内存资源紧张不想建 HashMap ✅ 大范围顺序扫描场景什么时候不要指望 Merge Join❌ 没有索引需临时排序代价大 ❌ 非等值 Join ❌ Join Key 被函数处理过 ❌ 数据低基数大量重复值三种策略终极对比Nested LoopHash JoinMerge Join比喻两层 for 循环建字典查字典双指针合并有序列表复杂度O(N × M)O(N M)O(N M)内存低中极低依赖索引内表需要不需要必须适合场景外表极小大表通用大表双方有索引核心记忆Merge Join 先排好序再双指针各走一遍。排序靠索引索引有了就免费索引没有就代价大。

相关文章:

PostgreSQL Merge Join 大白话详解

用生活中最直观的例子,彻底搞懂 Merge Join 是什么、为什么快、什么时候用。一、先从生活场景开始 场景一:两摞乱序试卷找同学 期末考试,老师手里有两摞试卷: A 摞:数学试卷,500 份,乱序堆放B 摞…...

PostgreSQL Join 执行策略(Nested Loop、Hash Join、Merge Join)与 NOT EXISTS 优化

以集成数据压缩 SQL 优化为例,用大白话讲清楚 Nested Loop、Hash Join、Merge Join 三种执行策略。一、背景:一条慢 SQL 引发的思考 在对上游下发数据做压缩时,有这样一条 UPDATE SQL: -- ❌ 原始写法 UPDATE magellan_nk_order_i…...

Godot 2D随机地图三大静默故障:黑屏、穿墙、寻路失败的根源与修复

1. 为什么刚上手Godot做2D随机地图就总卡在“生成出来是黑的”“角色穿墙”“房间连不通”这三件事上?如果你是刚从Unity或GameMaker转来Godot,或者第一次用GDScript写程序逻辑的新手,大概率已经在2D随机地图生成这个环节反复摔过跟头——不是…...

基于Arduino Uno与MQ-2传感器的智能气体检测报警系统DIY全攻略

1. 项目概述与核心思路最近在捣鼓家里的智能安防,琢磨着能不能自己做一个成本可控、反应灵敏的气体检测报警装置。市面上成品烟雾报警器虽然成熟,但要么功能单一,要么价格不菲,而且很难根据自己的需求进行定制化调整,比…...

泰拉瑞亚地图编辑器:从像素画布到创意世界的蜕变之旅

泰拉瑞亚地图编辑器:从像素画布到创意世界的蜕变之旅 【免费下载链接】Terraria-Map-Editor TEdit - Terraria Map Editor - TEdit is a stand alone, open source map editor for Terraria. It lets you edit maps just like (almost) paint! It also lets you cha…...

机器学习赋能矩方法:破解稀薄气体强非平衡流动模拟难题

1. 项目概述:当矩方法遇见机器学习在计算流体力学领域,模拟稀薄气体动力学和强非平衡流动,一直是个让工程师和科学家们头疼的“硬骨头”。想象一下,你正在设计一架高超音速飞行器,当它以数倍音速在大气层边缘飞行时&am…...

Godot 4.3随机地图性能优化:避开TileMap与RNG陷阱

1. 为什么刚写完第一版随机地图就崩溃?——从“能跑”到“能用”的真实断层你兴冲冲地照着教程敲完几十行GDScript,RandomNumberGenerator初始化了,for x in range(width)循环也套好了,甚至还在_draw()里用draw_rect()把每个格子都…...

告别复杂模型:用Python+OpenCV+dlib实现简易驾驶员疲劳监测(附完整代码)

轻量级驾驶员疲劳监测系统:PythonOpenCVdlib实战指南 在长途驾驶或夜间行车时,疲劳是导致交通事故的重要因素之一。传统基于嵌入式设备的疲劳监测系统往往需要专用硬件,增加了开发成本和部署难度。本文将介绍如何利用Python生态中的OpenCV和d…...

NPU跑LLM实战指南:KV Cache动态性如何突破硬件限制

NPU跑LLM实战指南:KV Cache动态性如何突破硬件限制 副标题: 从预分配+Attention Mask到三层软件栈,完整解析NPU推理架构 痛点:为什么NPU跑LLM这么难? LLM的生成机制和NPU的硬件特性存在根本冲突: LLM特性 NPU特性 冲突点 逐token生成 固定shape执行 KV Cache动态增长 动…...

如何用Untrunc拯救损坏视频?2025年终极MP4修复工具完全指南

如何用Untrunc拯救损坏视频?2025年终极MP4修复工具完全指南 【免费下载链接】untrunc Restore a damaged (truncated) mp4, m4v, mov, 3gp video. Provided you have a similar not broken video. 项目地址: https://gitcode.com/gh_mirrors/unt/untrunc 当你…...

基于ISDN信令的来电语音播报系统:从原理到树莓派实现

1. 项目概述:一个基于ISDN的来电语音播报系统如果你家里或办公室里还有一台老式的ISDN路由器,别急着把它当电子垃圾处理掉。我最近就利用手头一台闲置的ISDN路由器,折腾出了一个挺有意思的小玩意儿:一个能自动识别来电号码&#x…...

纯硬件实现I2C协议:从逻辑门到传感器通信的深度实践

1. 项目概述:用纯硬件“解剖”I2C总线很多朋友在玩传感器,尤其是温湿度传感器时,都绕不开I2C这个通信协议。市面上绝大多数的教程和方案,都会告诉你:找个单片机(比如Arduino、STM32)&#xff0c…...

Python Android打包终极指南:5个实战技巧解决移动开发痛点

Python Android打包终极指南:5个实战技巧解决移动开发痛点 【免费下载链接】python-for-android Turn your Python application into an Android APK 项目地址: https://gitcode.com/gh_mirrors/py/python-for-android Python-for-Android(简称p4…...

为什么你明明很努力,领导却总看不到?问题出在这

许多测试同行在深夜加班排查Bug时,在凌晨赶写自动化脚本时,在对着海量数据做性能分析时,内心都会浮现一个共同的困惑:我明明已经这么拼了,为什么在领导眼里,我依然是个“找茬的”,而不是“创造价…...

ROS机器人仿真架构解析:基于wpr_simulation的移动操作机器人技术实现

ROS机器人仿真架构解析:基于wpr_simulation的移动操作机器人技术实现 【免费下载链接】wpr_simulation 项目地址: https://gitcode.com/gh_mirrors/wp/wpr_simulation 在机器人操作系统(ROS)开发领域,硬件依赖和测试成本一直是制约算法迭代效率的…...

ImageGlass:一个支持90+图像格式的轻量级Windows图片查看器

ImageGlass:一个支持90图像格式的轻量级Windows图片查看器 【免费下载链接】ImageGlass 🏞 A lightweight, versatile image viewer 项目地址: https://gitcode.com/gh_mirrors/im/ImageGlass 还在为Windows自带的图片查看器功能单一而烦恼吗&…...

JavaScript对象创建:告别繁琐,四种灵活写法一学就会

在JavaScript里,创建对象的这般方法常把刚开始学习的新手弄得困惑不已,好像无论走哪条道都行得通,可又不清楚该挑哪一条才好。我编写JavaScript都有十几年功夫了,对象创建这事差不多每天都会碰到可谓基础技能。它不像变量声明那般…...

终极崩坏星穹铁道自动化指南:3分钟掌握解放双手的智能游戏伴侣

终极崩坏星穹铁道自动化指南:3分钟掌握解放双手的智能游戏伴侣 【免费下载链接】StarRailAssistant 崩坏:星穹铁道自动化 | 崩坏:星穹铁道自动锄大地 | 崩坏:星穹铁道锄大地 | 自动锄大地 | 基于模拟按键 项目地址: https://git…...

AI 应用原型开发阶段利用 Taotoken 快速进行多模型效果对比

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 AI 应用原型开发阶段利用 Taotoken 快速进行多模型效果对比 在构建一个 AI 应用的原型时,开发者常常面临一个核心问题&…...

怎么理解Filter不是在afterCompetition里面remove掉ThreadLocal里面的东西,而是说在finally块里面remove

文章目录1. 核心原因:Filter 的“套娃(洋葱圈)”执行模型2. 为什么不能(也无法)在这里用 afterCompletion?维度一:Filter 拿不到 afterCompletion维度二:生命周期顺序的致命冲突总结…...

实测对比,使用Taotoken聚合接口后Agent任务延迟与稳定性观感

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 实测记录:使用 Taotoken 聚合接口后 Agent 任务延迟与稳定性观感 效果展示类,记录将原有基于单一 API 的 A…...

USB数据隔离器DIY:物理切断数据线,防范充电攻击

1. 移动设备充电安全:一个被忽视的“物理后门”你可能每天都在做这件事:手机或平板电脑电量告急,随手拿起一根数据线,插在办公室的公共电脑、机场的充电站,甚至是朋友提供的充电宝上。这看起来再平常不过了&#xff0c…...

如何让旧款Mac运行最新系统:OpenCore Legacy Patcher完整指南

如何让旧款Mac运行最新系统:OpenCore Legacy Patcher完整指南 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 想让你的老旧Mac设备重新焕发活力&a…...

抖音批量下载助手:一键构建你的专属视频素材库

抖音批量下载助手:一键构建你的专属视频素材库 【免费下载链接】douyinhelper 抖音批量下载助手 项目地址: https://gitcode.com/gh_mirrors/do/douyinhelper 还在为手动保存抖音视频而烦恼吗?想要批量获取心仪创作者的精彩内容却无从下手&#x…...

使用Taotoken CLI工具一键配置多开发环境下的统一模型接入点

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 使用Taotoken CLI工具一键配置多开发环境下的统一模型接入点 在团队协作或管理多个AI应用项目时,一个常见的痛点是每个…...

3大突破性功能:用HiveWE革新你的魔兽争霸III地图创作体验

3大突破性功能:用HiveWE革新你的魔兽争霸III地图创作体验 【免费下载链接】HiveWE A Warcraft III world editor. 项目地址: https://gitcode.com/gh_mirrors/hi/HiveWE 还在为传统魔兽争霸III编辑器缓慢的加载速度和复杂的操作界面而烦恼吗?Hive…...

如何高效实现Windows自动化鼠标点击:AutoClicker完整实战指南

如何高效实现Windows自动化鼠标点击:AutoClicker完整实战指南 【免费下载链接】AutoClicker AutoClicker is a useful simple tool for automating mouse clicks. 项目地址: https://gitcode.com/gh_mirrors/au/AutoClicker AutoClicker是一款专业的Windows桌…...

机器学习力场攻克Peierls相变动力学:从对称性描述符到畴生长标度律

1. 项目概述:当机器学习遇见Peierls相变在凝聚态物理和材料科学的前沿,我们常常被一个核心问题所困扰:如何精确地模拟那些由电子和晶格(原子)强烈耦合所驱动的复杂动力学过程?这类系统,比如电荷…...

WarcraftHelper:让经典魔兽争霸3完美适配现代电脑的终极解决方案

WarcraftHelper:让经典魔兽争霸3完美适配现代电脑的终极解决方案 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为魔兽争霸3在现代操…...

数字合成器d-FORMANT:从模拟经典到数字复刻的工程实践

1. 项目概述:从模拟经典到数字复刻如果你对合成器稍有了解,或者对电子音乐制作背后的硬件感兴趣,那么“FORMANT”这个名字你一定不陌生。它最初是上世纪70年代由《Elektor》杂志发布的一款模拟单音合成器,以其清晰的模块化设计和出…...