PostgreSQL 明明有索引却选了 Nested Loop:从行数误判修正执行计划
同一条订单查询小参数时几十毫秒大参数时却长时间占用数据库EXPLAIN显示优化器预计返回 12 行实际执行产生了十几万行随后 Nested Loop 的内表被反复扫描。问题不在于 PostgreSQL “不认识索引”而在于它基于错误的行数估计选错了连接路径。本文用一个country与currency强相关的例子说明如何找到第一次估算分叉。文中的 SQL 是可执行的诊断样例但这里没有连接你的数据库因此不会把示例结果写成实测结论。先复现两个相关条件被当成彼此独立假设订单表中中国区订单几乎都以 CNY 结算CREATETABLEorders(idbigintGENERATED ALWAYSASIDENTITYPRIMARYKEY,customer_idbigintNOTNULL,countrytextNOTNULL,currencytextNOTNULL,created_at timestamptzNOTNULL);CREATEINDEXidx_orders_customer_createdONorders(customer_id,created_atDESC);只收集单列统计信息时规划器可能分别估计country CN与currency CNY的选择率再把两者相乘。真实数据中的相关性没有进入模型中间结果便会被严重低估。在测试库中用下面的命令保留执行证据EXPLAIN(ANALYZE,BUFFERS,SETTINGS,FORMATTEXT)SELECTc.id,o.id,o.created_atFROMcustomersAScJOINordersASoONo.customer_idc.idWHEREo.countryCNANDo.currencyCNYANDo.created_atnow()-interval30 days;ANALYZE会真的执行查询不要把修改型 SQL 原样放到生产环境。排查时从计划树内层向外找第一个rows与actual rows明显分叉的节点并把loops一起看最外层耗时只是结果第一次误判才是线索。不要先禁用连接算法先检查规划器掌握了什么先查看自动分析时间和列分布SELECTrelname,last_analyze,last_autoanalyze,n_live_tupFROMpg_stat_user_tablesWHERErelnameIN(orders,customers);SELECTattname,n_distinct,most_common_vals,most_common_freqsFROMpg_statsWHEREschemanamepublicANDtablenameordersANDattnameIN(country,currency,customer_id);成功的诊断不是“强制走了 Hash Join”而是能回答三个问题统计信息是否过期、目标值是否在高频值列表中、多个过滤列是否存在业务相关性。若只是批量导入后统计信息陈旧先执行ANALYZE orders若误差稳定来自相关列再考虑扩展统计CREATESTATISTICSst_orders_country_currency(dependencies,mcv)ONcountry,currencyFROMorders;ANALYZEorders;dependencies描述列依赖mcv保存常见组合。它们帮助过滤条件估算但不会自动替代缺失的连接索引也不能修复写错的 Join 条件。做一个反事实实验而不是永久关闭 Nested Loop在事务内临时改变规划器开关可以验证“另一类计划是否值得继续调查”BEGIN;SETLOCALenable_nestloopoff;EXPLAIN(ANALYZE,BUFFERS)SELECT/* 同一条查询参数保持一致 */;ROLLBACK;这只是反事实实验。若另一计划更合适应继续修正统计信息、SQL 或索引而不是在全局配置中禁用 Nested Loop。小结果集驱动索引查找时Nested Loop 往往正是正确选择。还要防止只验证一组参数。把典型小客户、普通客户和头部客户的参数各选一组分别保存计划。预备语句使用通用计划时参数分布差异尤其容易被平均值掩盖。验收修复关注估算误差而非计划节点名称可以把计划保存为 JSON再检查目标节点的估算倍率psql$DATABASE_URL-X-vON_ERROR_STOP1-Atc\EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) SELECT c.id, o.id FROM customers c JOIN orders o ON o.customer_idc.id WHERE o.countryCN AND o.currencyCNY;\plan.json python-mjson.tool plan.json/dev/nulltest-splan.json上述命令的可验证成功条件是psql退出码为 0、plan.json非空且能被 JSON 解析。性能层面的验收还需比较修改前后相同数据快照、相同参数和相同缓存条件下的计划重点记录首次分叉节点的估算/实际行数倍率、缓冲区读取和总执行时间。失败条件包括估算误差没有缩小、只对单一参数改善或其他高频查询出现回退。优化器调优的目标不是让 SQL 永远使用某个索引而是让成本模型获得足够准确的输入。先定位第一次估错再决定更新统计、添加扩展统计、调整索引还是改写查询通常比直接改全局成本参数更可控。

相关新闻

第二章 c语言的基本元素--2.2 关键字

第二章 c语言的基本元素--2.2 关键字

文章目录2.2.1 register关键字一、register使用register修饰符的注意点2.2.2 static关键字1.1 修饰变量2.2 修饰函数2.2.1 register关键字 元素——2.2 关键字 关键字(Keywords)是C语言中具有特殊含义的保留字,它们构成了C语言语法的核心骨…

2026/7/27 19:25:09 阅读更多 →
20个Alfred自动化工具:让你的Mac工作效率翻倍的终极指南

20个Alfred自动化工具:让你的Mac工作效率翻倍的终极指南

20个Alfred自动化工具:让你的Mac工作效率翻倍的终极指南 【免费下载链接】favoritesWorkflow4Alfred 项目地址: https://gitcode.com/GitHub_Trending/fa/favoritesWorkflow4Alfred 在追求极致效率的Mac用户群体中,Alfred作为强大的启动器和自动…

2026/7/27 19:24:09 阅读更多 →
如何快速搭建Logseq与Anki同步:终极使用指南

如何快速搭建Logseq与Anki同步:终极使用指南

如何快速搭建Logseq与Anki同步:终极使用指南 【免费下载链接】logseq-anki-sync An logseq to anki syncing plugin with superpowers - image occlusion, card direction, incremental cards, and a lot more. 项目地址: https://gitcode.com/gh_mirrors/lo/logs…

2026/7/27 19:24:09 阅读更多 →

最新新闻

Logseq Anki Sync:如何将笔记知识高效转化为记忆卡片?

Logseq Anki Sync:如何将笔记知识高效转化为记忆卡片?

Logseq Anki Sync:如何将笔记知识高效转化为记忆卡片? 【免费下载链接】logseq-anki-sync An logseq to anki syncing plugin with superpowers - image occlusion, card direction, incremental cards, and a lot more. 项目地址: https://gitcode.co…

2026/7/27 19:31:11 阅读更多 →
从0到1:使用Playlist-AutoUpdater构建个人自动更新播放列表

从0到1:使用Playlist-AutoUpdater构建个人自动更新播放列表

从0到1:使用Playlist-AutoUpdater构建个人自动更新播放列表 【免费下载链接】Playlist-AutoUpdater Auto-Update your M3U Playlists every day without needing an app, with the same link. 项目地址: https://gitcode.com/gh_mirrors/ta/Playlist-AutoUpdater …

2026/7/27 19:31:11 阅读更多 →
终极指南:使用XXMI-Launcher轻松管理多个游戏模组

终极指南:使用XXMI-Launcher轻松管理多个游戏模组

终极指南:使用XXMI-Launcher轻松管理多个游戏模组 【免费下载链接】XXMI-Launcher Modding platform for GI, HSR, WW and ZZZ 项目地址: https://gitcode.com/gh_mirrors/xx/XXMI-Launcher XXMI-Launcher是一款革命性的游戏模组管理平台,专为热门…

2026/7/27 19:31:11 阅读更多 →
如何在iOS设备上轻松安装第三方应用:App Installer完整指南

如何在iOS设备上轻松安装第三方应用:App Installer完整指南

如何在iOS设备上轻松安装第三方应用:App Installer完整指南 【免费下载链接】App-Installer On-device IPA installer 项目地址: https://gitcode.com/gh_mirrors/ap/App-Installer App Installer是一款强大的iOS设备应用安装工具,让你无需通过Ap…

2026/7/27 19:31:11 阅读更多 →
零基础快速上手:go-cqhttp QQ机器人开发完全指南

零基础快速上手:go-cqhttp QQ机器人开发完全指南

零基础快速上手:go-cqhttp QQ机器人开发完全指南 【免费下载链接】go-cqhttp cqhttp的golang实现,轻量、原生跨平台. 项目地址: https://gitcode.com/gh_mirrors/go/go-cqhttp 想要在几分钟内搭建一个功能强大的QQ机器人吗?go-cqhttp作…

2026/7/27 19:31:11 阅读更多 →
Leetcode 494. 目标和

Leetcode 494. 目标和

心路历程: 这道题的递推关系很明显,类似于一个背包问题,按照背包问题的建模方式即可。 状态:从头开始以nums[i]结尾的子数组,当前目标和 动作:选择加号还是减号 返回值:有多少种可能的组合 解法…

2026/7/27 19:30:10 阅读更多 →

日新闻

【JAVA毕设源码分享】基于SpringBoot的社区智能垃圾管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于SpringBoot的社区智能垃圾管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/27 0:00:54 阅读更多 →
SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

1. 项目概述:从寄存器手册到实战指南 如果你手头有一份类似德州仪器(TI)TMS320x240xA系列DSP的SPI模块技术手册,看着里面密密麻麻的寄存器位定义、时序图和公式,是不是感觉头大?这份资料虽然权威&#xff0…

2026/7/27 0:00:54 阅读更多 →
【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/27 0:00:54 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/27 4:33:59 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/27 6:31:56 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/27 4:01:12 阅读更多 →

月新闻