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

PostgreSQL EXISTS vs IN 性能对比详解

一、背景案例在 Magellan 数据压缩场景中需要删除旧批次olderBatch中与新批次newerBatch重叠的数据。IN 写法DELETEFROMmagellan_cn_order_inboundWHEREversion_number20260521172049432ANDorder_idIN(SELECTorder_idFROMmagellan_cn_order_inbound bWHEREb.version_number20260522000707011)EXISTS 写法DELETEFROMmagellan_cn_order_inboundWHEREversion_number20260521172049432ANDEXISTS(SELECT1FROMmagellan_cn_order_inbound bWHEREb.version_number20260522000707011ANDb.order_idmagellan_cn_order_inbound.order_id)二、执行逻辑的本质区别IN 的执行逻辑第一步执行子查询物化整个结果集到内存 SELECT order_id FROM ... WHERE version_number newerBatch → 结果集[id_1, id_2, id_3, ... id_500万] 全部加载到内存 第二步对外层每一行在结果集中做查找 WHERE order_id IN [id_1, id_2, ... id_500万]问题子查询必须全部执行完才能开始外层过滤500 万条record_id全部物化到内存内存压力大如果子查询结果集非常大可能触发 Hash 构建占用大量工作内存work_memEXISTS 的执行逻辑第一步外层取一行olderBatch 中的某条记录 第二步拿这行的 record_id 去子查询中查找 SELECT 1 FROM ... WHERE version_number newerBatch AND order_id 当前行的id 第三步找到第一条匹配 → 立即返回 TRUE短路退出子查询 没找到 → 返回 FALSE 第四步重复处理外层下一行优势子查询不需要物化全部结果找到即停每次子查询都能命中主键索引(version_number, record_id)极快内存占用极低三、结合本案例的索引分析表主键(version_number, order_id)操作INEXISTS子查询索引使用全扫 newerBatch 所有行物化每次用主键精确查(newerBatch, 当前id)外层索引使用用version_numberolderBatch命中同左内存使用高物化整个子查询极低逐行匹配短路优化❌ 无✅ 找到即停四、执行计划对比示意IN 的典型执行计划Delete on magellan_cn_order_inbound - Hash Semi Join Hash Cond: (a.record_id b.record_id) - Index Scan on magellan_cn_order_inbound (versionolderBatch) - Hash - Index Scan on magellan_cn_order_inbound b (versionnewerBatch) ★ 先把 newerBatch 全部扫出来构建 Hash 表EXISTS 的典型执行计划Delete on magellan_cn_order_inbound - Nested Loop Semi Join - Index Scan on magellan_cn_order_inbound (versionolderBatch) - Index Scan on magellan_cn_order_inbound b Index Cond: (version_numbernewerBatch AND record_id外层当前id) ★ 每次用主键精确查找到即停PostgreSQL 实际上很智能对IN也可能优化为 Hash Semi Join但当子查询结果集超过work_mem时性能会急剧下降。五、什么时候 IN 反而更快EXISTS 也不是万能的以下场景 IN 可能更优场景推荐子查询结果集很小几十条IN结果集小物化代价低逻辑简单子查询结果集很大百万级EXISTS避免物化逐行匹配更省内存外层表数据量远小于子查询IN外层循环少Hash 查找快需要去重语义IN自动去重六、本案例结论magellan_cn_order_inbound 数据量千万级 newerBatch 数据量可能 200万500万条推荐使用 EXISTSDELETEFROMmagellan_cn_order_inboundWHEREversion_number#{olderBatch}ANDEXISTS(SELECT1FROMmagellan_cn_order_inbound bWHEREb.version_number#{newerBatch}ANDb.order_idmagellan_cn_order_inbound.order_id)原因newerBatch 数据量大IN 会物化数百万record_id到内存主键(version_number, record_id)可被 EXISTS 子查询精确命中EXISTS 短路特性在重叠率高时效果更明显找到即停七、一句话总结IN是先把答案全算出来再去对照EXISTS是对照一条有结果立刻告诉我不用全算完。数据量越大EXISTS 的优势越明显。
http://www.gsyq.cn/news/1394919.html

相关文章:

  • 遥感影像解译:揭秘植被、水体、岩石、雪与土壤的独特光谱指纹
  • 从手机陀螺仪到无人机:聊聊万向锁(Gimbal Lock)那些让你设备‘晕头转向‘的瞬间
  • 图神经网络与强化学习融合:电力系统暂态稳定预防控制的AI新范式
  • 告别覆盖率合并混乱:手把手教你用VCS/URG的-cm_hier和-mapfile精准管理数据
  • 基于ESP32与边缘AI的动物行为监测系统:从传感器到智能决策
  • 解决 cc-connect + Claude Code 图片识别问题
  • 精准窗口尺寸控制:3步掌握WindowResizer的高级应用技巧
  • 无人船的基本结构(TODO)
  • Excel两列数据比对:从找不同到数据一致性校验
  • Unity启动页帧动画实现原理与工程实践
  • 从零到一:30分钟掌握nomic-embed-text-v1文本嵌入模型部署全攻略 [特殊字符]
  • 从PLC对接到数字孪生闭环,AI Agent在离散制造中的全栈集成路径,深度拆解3类产线适配方案
  • 2026 百色房屋漏水不用愁!雨中匠人免费上门检测,本地专业防水公司常年TOP1!卫生间免砸砖防水,快速解决您的烦恼。权威!靠谱!稳定!售后无忧!!! - 防水百科
  • OpenCV鱼眼矫正踩坑实录:手把手教你读懂fisheye::initUndistortRectifyMap源码里的数学
  • 浏览器视频资源嗅探神器:猫抓插件让你轻松保存网页视频资源
  • Burp Suite弱口令检测实战:从响应特征到多维认证逆向
  • 内容创作团队借助Taotoken多模型能力提升文案生成效率与多样性
  • 从POV原理到静音时钟:非接触供电与动平衡实践
  • 从LSB隐写到Nihilist密码:一次完整的Misc实战解密之旅
  • 深度实践ShiroAttack2:揭秘开源安全工具的架构创新与实战应用
  • 3分钟掌握iOS应用签名:终极图形化工具完整指南
  • 如何通过 Python 调用 Taotoken 的多模型 API 快速构建应用
  • 关联规则挖掘实战:从超市货架到电商推荐的商业逻辑
  • 部署/推理大模型的程序架构(推理引擎/框架)及其开源协议
  • 从攻击到防御:手把手教你用Hydra破解自家Win10后,如何设置强密码策略和账户锁定
  • EtherCAT PDO映射实战:从XML文件到STM32代码,搞定一个自定义模拟量变量
  • Blender导出OBJ到Unity模型发白的三大断点与解决方案
  • CTGAN完全教程:如何用条件GAN生成高质量的合成表格数据
  • AI工具协同失效诊断手册:用3个指标(响应熵值、上下文衰减率、意图偏移度)秒判工作流亚健康
  • 终于搞懂 XSS 为什么能盗号了:Cookie、Session、HttpOnly 一次讲明白