执行计划一夜之间变了?别查代码了,是统计信息在“说谎“
大家好我是小耶写功课只是为了我踩过的坑你们别再踩了有个经典的凌晨惊魂场景某条核心SQL跑了半年都没问题每天几十万次执行响应时间稳定在5毫秒以内。某天凌晨三点监控告警疯狂弹窗——这条SQL突然飙到5秒CPU打满整个系统雪崩。DBA赶到现场第一反应是看代码有没有人改。没有。看索引有没有人删。没有。看数据量有没有暴涨。也没有。最后查下来原因让人无语统计信息过期了。数据库优化器拿着一份过时的情报给这条SQL选了一条错误的执行计划。今天把执行计划突变的底层原理、排查手段和预防机制一次讲清楚。一、先搞懂几个概念执行计划Execution Plan数据库执行一条SQL的具体步骤。先走哪个索引、先JOIN哪张表、用什么JOIN方式Nested Loop、Hash Join、Merge Join这些决策组合起来就是执行计划。优化器Optimizer数据库里的决策引擎负责为每条SQL选择最优的执行计划。它不跑SQL只猜哪种执行方式最快。统计信息Statistics优化器做决策的依据。包括表的总行数、每列的数据分布最大值、最小值、NULL占比、直方图、索引的选择性不同值的数量等。本质上就是优化器眼中的数据库快照。基数估计Cardinality Estimation优化器预估每一步会返回多少行数据。预估准了执行计划就优预估偏了就可能选错索引、选错JOIN顺序。CBOCost-Based Optimizer基于成本的优化器。优化器根据统计信息计算每种执行计划的成本CPU消耗、IO次数、内存占用选成本最低的那个。理解了这些概念就能回答一个核心问题为什么执行计划会突然变二、执行计划为什么会背叛你统计信息过期优化器拿到的是过期情报这是最常见的原因。统计信息不是实时更新的大多数数据库是定期收集或手动触发。假设你有一张订单表平时100万行统计信息也是按这个量级收集的。某天大促数据量涨到500万但统计信息还没更新。优化器依然认为表里只有100万行——于是选择了全表扫描因为它觉得100万行全表扫比走索引快。实际上500万行全表扫描直接卡死。统计信息 ≠ 实时数据它是一份延迟的快照。数据倾斜平均值骗了优化器即使统计信息是新的也可能因为数据分布不均匀而误导优化器。比如一个订单表的status列99%的数据是COMPLETED1%是PENDING。如果统计信息只记录了平均分布没有收集直方图优化器会认为每个状态的占比差不多。当你查询status COMPLETED时优化器预估返回1000行总行数10万的1/100实际返回99000行——走索引反而比全表扫慢几十倍。索引变化新增索引不一定是好事开发同学看到慢SQL第一反应是加索引。加完索引后统计信息更新优化器重新评估所有可用索引可能选出一个更差的执行计划。加索引 ≠ SQL变快它只是给优化器多了一个选择而这个选择可能是错的。参数变更看似无关的配置调整optimizer_mode从ALL_ROWS改为FIRST_ROWSoptimizer_features_enable版本升级后行为变化statistics_level从TYPICAL改为BASIC停止收集部分统计信息这些参数调整不会立刻生效但下一次硬解析时优化器的决策逻辑可能完全改变。三、执行计划突变的排查步骤第一步确认是不是执行计划变了-- Oracle SELECT * FROM v$sql_plan WHERE sql_id your_sql_id; -- MySQL (8.0) EXPLAIN FORMATTREE SELECT ...; -- PostgreSQL EXPLAIN (ANALYZE, BUFFERS) SELECT ...; -- 对比历史执行计划 -- Oracle: DBMS_XPLAN.DISPLAY_AWR(your_sql_id)重点对比访问路径全表扫 vs 索引扫描、JOIN顺序、JOIN方式、预估行数 vs 实际行数。第二步检查统计信息是否过期-- Oracle查看表的统计信息收集时间 SELECT table_name, last_analyzed, num_rows, blocks FROM user_tables WHERE table_name YOUR_TABLE; -- MySQL查看InnoDB表统计信息 SHOW TABLE STATUS LIKE your_table; -- PostgreSQL查看统计信息 SELECT last_analyze, last_autoanalyze, n_live_tup, n_dead_tup FROM pg_stat_user_tables WHERE relname your_table;如果last_analyzed是几天甚至几周前而这段时间数据变化超过10%基本可以判定统计信息过期。第三步对比预估行数和实际行数这是判断优化器是否误判的关键指标。-- 执行SQL时开启实际执行统计 -- Oracle: EXPLAIN PLAN FOR ... 然后 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); -- MySQL: EXPLAIN ANALYZE SELECT ...; -- PostgreSQL: EXPLAIN ANALYZE SELECT ...;如果某一步的预估行数estimated rows和实际行数actual rows相差10倍以上说明基数估计严重失真执行计划很可能选错了。第四步检查是否有绑定变量窥探问题绑定变量第一次执行时优化器会窥探变量值来生成执行计划。后续执行直接复用这个计划即使变量值的数据分布差异很大。比如第一次传的是status PENDING只有100行优化器选了索引扫描。后面传的是status COMPLETED99000行还是走索引——但全表扫描反而更快。四、预防执行计划突变的4种手段手段一合理设置统计信息收集策略不要完全依赖自动收集根据业务特点定制策略适用场景收集频率自动收集 默认阈值数据变化平稳的普通表系统自动触发手动定时收集数据批量导入/删除的表每天凌晨或批量操作后锁定统计信息历史归档表数据不变化收集一次后锁定收集直方图数据分布严重倾斜的列按需收集-- Oracle: 手动收集统计信息含直方图 EXEC DBMS_STATS.GATHER_TABLE_STATS(SCHEMA, TABLE_NAME, method_opt FOR COLUMNS SIZE AUTO skewed_column); -- MySQL: 手动分析表 ANALYZE TABLE your_table; -- PostgreSQL: 手动分析 ANALYZE your_table;手段二使用执行计划基线Plan BaselineOracle提供了SQL Plan ManagementSPM可以把好的执行计划锁定下来即使统计信息变化也不让优化器切换到更差的计划。-- Oracle: 创建执行计划基线 DECLARE l_plans_loaded PLS_INTEGER; BEGIN l_plans_loaded : DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE( sql_id your_sql_id); END;金仓数据库也提供了类似的执行计划管理能力。通过DBMS_SPM兼容包可以将经过验证的优秀执行计划固定下来避免因统计信息变化导致的性能波动。同时支持执行计划演化evolve在确认新计划更优后才自动切换。手段三SQL Profile / OutlineSQL Profile是优化器的纠正器。当发现某条SQL的执行计划不理想时可以创建一个SQL Profile告诉优化器这条SQL按这个方式执行。-- Oracle: 使用SQL TUNING ADVISOR DECLARE l_tuning_task VARCHAR2(30); BEGIN l_tuning_task : DBMS_SQLTUNE.CREATE_TUNING_TASK(sql_id your_sql_id); DBMS_SQLTUNE.EXECUTE_TUNING_TASK(l_tuning_task); DBMS_SQLTUNE.ACCEPT_SQL_PROFILE(task_name l_tuning_task); END;手段四监控统计信息变化建立监控机制在统计信息过期前主动预警-- 找出统计信息超过7天未更新的表 SELECT table_name, last_analyzed, ROUND((SYSDATE - last_analyzed), 1) as days_since_analyze FROM user_tables WHERE last_analyzed SYSDATE - 7 ORDER BY last_analyzed;建议在监控系统中加入以下告警项核心表统计信息超过X天未更新单表数据变化量超过上次统计的10%执行计划发生变更对比AWR报告五、总结执行计划突变的本质是优化器拿着一份过时的地图给你指了一条错误的路。代码没改、索引没动SQL突然变慢——不要急着翻代码先查统计信息。排查执行计划问题按这个顺序来对比执行计划确认是不是执行计划变了不是SQL本身的问题检查统计信息last_analyzed多久了数据变化量超过10%了吗预估 vs 实际基数估计偏差超过10倍优化器就失明了绑定变量第一次执行的变量值可能不适合后续的变量值预防胜于治疗统计信息收集策略 执行计划基线 变化监控三管齐下让慢SQL扼杀在摇篮里。小耶在手SQL不愁。还有什么想了解的欢迎留言小耶一定知无不言言无不尽……我们下次见~

相关新闻

大模型采样参数调参全解:Temperature、Top_k、Top_p 实操指南

大模型采样参数调参全解:Temperature、Top_k、Top_p 实操指南

不少开发者在调用大模型 API 时,只会配置接口地址、模型名称与密钥,面对 Temperature、Top_p、Top_k 三大采样参数一头雾水。调参全靠盲目试错:想要严谨专业的报告,AI 却天马行空胡乱编造;需要创意故事、营销文案&…

2026/7/30 11:33:37 阅读更多 →
从流程图到可执行代码:基于Activiti的流程引擎完整生命周期解析

从流程图到可执行代码:基于Activiti的流程引擎完整生命周期解析

1. 项目概述:从流程图到可执行代码的旅程在任何一个涉及审批、流转或自动化处理的软件项目中,流程引擎都是核心的“中枢神经系统”。我们经常在需求文档里看到用BPMN(业务流程模型与标记法)画的流程图,那些圆角矩形、菱…

2026/7/30 11:33:36 阅读更多 →
从初级到高级,网络安全攻防工程师AD认证三级课程体系深度解析

从初级到高级,网络安全攻防工程师AD认证三级课程体系深度解析

网络安全攻防工程师(AD)认证设置初级、中级、高级三个等级,形成无断点的职业能力成长路径。每个级别都有明确的培养目标和课程体系,学员可以根据自身基础选择起点,逐步进阶。本文将深度解析AD认证三级课程体系的详细内…

2026/7/30 11:32:36 阅读更多 →

最新新闻

RPG Maker MV 解密工具完整指南:轻松解锁加密资源文件

RPG Maker MV 解密工具完整指南:轻松解锁加密资源文件

RPG Maker MV 解密工具完整指南:轻松解锁加密资源文件 【免费下载链接】RPG-Maker-MV-Decrypter You can decrypt RPG-Maker-MV Resource Files with this project ~ If you dont wanna download it, you can use the Script on my HP: 项目地址: https://gitcode…

2026/7/30 11:40:39 阅读更多 →
通用多级树形结构工具类设计与优化实践

通用多级树形结构工具类设计与优化实践

1. 多级结构工具类设计背景与核心价值 在日常开发中,处理树形结构数据是个高频需求。无论是后台管理系统中的多级菜单、社区平台的多级评论回复,还是企业组织架构中的多级部门关系,本质上都是对父子层级关系的建模。最近在重构公司权限系统时…

2026/7/30 11:40:39 阅读更多 →
5分钟搞定B站视频转文字:开源神器bili2text完整使用指南

5分钟搞定B站视频转文字:开源神器bili2text完整使用指南

5分钟搞定B站视频转文字:开源神器bili2text完整使用指南 【免费下载链接】bili2text Bilibili视频转文字,一步到位,输入链接即可使用 项目地址: https://gitcode.com/gh_mirrors/bi/bili2text 还在为手动抄写B站视频内容而烦恼吗&…

2026/7/30 11:40:39 阅读更多 →
开源AI代理框架Hermes Agent开发指南

开源AI代理框架Hermes Agent开发指南

1. Hermes Agent项目概述 Hermes Agent是一个开源的自主持续进化AI代理框架,它允许开发者构建能够独立执行复杂任务的智能体系统。这个项目最近在GitHub上获得了大量关注,主要因为它解决了传统AI代理的几个关键痛点:任务执行的连贯性、长期记…

2026/7/30 11:40:38 阅读更多 →
DPO 比 RLHF 省 60% 显存但效果差 8%?Taotoken 用 1000 条偏好数据实测对齐训练选型

DPO 比 RLHF 省 60% 显存但效果差 8%?Taotoken 用 1000 条偏好数据实测对齐训练选型

上周在 Taotoken 平台使用 PPO 接口微调 GPT-5.4 时,3 张 A100 的显存直接被爆,这引发了我们对大模型微调方案的深度思考。转而采用 DPO 后虽然训练速度实现翻倍,但人工评估发现生成质量出现明显波动——这个矛盾促使我们设计了一套完整的对照…

2026/7/30 11:40:38 阅读更多 →
直播关键词触发自动回复系统:从设计到实现

直播关键词触发自动回复系统:从设计到实现

背景数字人直播的核心优势之一是"24 小时在线",但"在线"不等于"互动"。没有弹幕响应,直播间的气氛会冷清,用户留存率低。本文从技术视角,拆解"关键词触发自动回复系统"的设计与实现&…

2026/7/30 11:39:38 阅读更多 →

日新闻

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 您是否曾因Windows系统盘空间不足而烦恼?是否遇到过设…

2026/7/30 0:00:13 阅读更多 →
如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 你是否曾经在浏览…

2026/7/30 0:00:13 阅读更多 →
“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

更多请点击: https://intelliparadigm.com 第一章:AI 教师备课辅助 AI 教师备课辅助系统正逐步成为教育数字化转型的核心支撑工具,它并非替代教师,而是通过语义理解、知识图谱与多模态生成能力,将教师从重复性劳动中解…

2026/7/30 0:00:13 阅读更多 →

周新闻

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

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

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

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

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

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

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

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

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

2026/7/29 15:00:03 阅读更多 →

月新闻