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

从索引设计到执行计划:一条慢查询的“体检”全流程

大家好,我是小耶,写功课只是为了我踩过的坑,你们别再踩了!

慢查询优化,很多人的做法是:看到SQL慢,先猜是不是没索引,加一个试试;不行就再换一个;还不行就改写SQL碰运气。这种做法效率低,而且往往治标不治本。

真正的优化应该是一套“体检”流程:从索引设计是否合理,到执行计划如何解读,再到统计信息是否准确,最后到SQL改写验证——形成一个完整的闭环。今天我就用一条真实的慢查询,把这个流程完整走一遍。

第一步:索引设计——地基没打好,后面全白费

很多慢查询的根源,不是优化器选错了,而是压根没有合适的索引。

设计索引有几个基本原则,这些原则不是背口诀,而是有底层逻辑支撑的。

  • 等值查询的列放左边,范围查询的列放右边​。原因是在B+Tree结构中,索引首先按最左列排序,当遇到范围查询(><BETWEEN)时,后续列无法继续使用索引。所以设计复合索引时,要把=的条件放在前面,><等范围条件放在后面。
  • 高选择性的列优先​。选择性 = 不重复值数量 / 总行数。选择性越高,索引过滤效果越好。比如身份证号的选择性接近1,而性别只有0.5。把高选择性的列放在复合索引前面,能更快缩小扫描范围。
  • 考虑覆盖索引​。如果查询需要的所有列都包含在索引中,就不需要回表,Extra会显示Using index。这能减少一半以上的I/O。

假设我们有这样一张订单表,经常执行查询“查询某店铺某状态下,最近一段时间的订单”:

SELECT order_id, amount, create_time FROM orders WHERE shop_id = 123 AND status = 'PAID' AND create_time > '2026-01-01';

根据上述原则,推荐的复合索引是(shop_id, status, create_time)shop_idstatus是等值查询且选择性较好,放在前面;create_time是范围查询,放在最后。同时这个索引覆盖了查询所需的order_idamount(需要回表)、create_time,部分实现了覆盖。

第二步:执行计划解读——让数据库告诉你问题在哪

索引建好了,但优化器是不是真的用了?这就要看执行计划。

执行上面查询的EXPLAIN,我们可能会看到这样的输出:

typekeykey_lenrowsExtra
refidx_shop_status_time823Using where

逐列解读:

  • type=ref:用了普通索引,效率良好,不是ALLindex,说明索引生效。
  • key:实际使用了我们创建的复合索引。
  • key_len=8shop_id(4字节)+status(假设4字节),说明只用到了前两列,create_time没有参与索引过滤。这是因为create_time是范围条件,索引在遇到范围后停止匹配,这是正常现象。
  • rows=23:优化器预估只扫描23行,非常好。
  • Extra=Using where:需要回表后过滤create_time,但23行回表代价很小。

这个执行计划本身是健康的。但如果rows很大,或者type=ALL,就说明索引设计或使用出了问题。

第三步:统计信息——为什么优化器会“瞎”选

有时候明明有合适的索引,优化器却选择了全表扫描。原因往往是统计信息过旧。

优化器选择索引时,依赖表的统计信息(总行数、不同值数量、数据分布等)。如果统计信息没有及时更新,优化器就会误判。比如一张表实际有100万行,但统计信息显示只有1万行,优化器可能认为全表扫描更快。

更新统计信息的命令是ANALYZE TABLE。建议在批量导入、大量删除或数据分布发生明显变化后执行。对于MySQL 8.0,统计信息默认是持久化的,但仍可能需要手动触发。

检查统计信息是否准确的一个简单方法:EXPLAIN中的rows估算值与实际行数相差是否巨大。如果差了一个数量级,大概率是统计信息过旧了。

第四步:验证优化——从EXPLAIN到EXPLAIN ANALYZE

在测试环境,我们可以使用EXPLAIN ANALYZE(MySQL 8.0.18+)来获得真实的执行信息,而不只是估算。它会真正执行SQL,并输出每个操作的实际耗时、实际扫描行数、循环次数等。这可以帮助我们确认优化器的估算是否准确,以及哪个步骤最耗时。

例如,执行EXPLAIN ANALYZE SELECT ...后,输出中会包含类似actual time=0.123..0.456 rows=23 loops=1的信息。如果actual time远超预期,或者rows与估算值差距很大,就需要进一步调查。

完整的优化闭环

从索引设计到执行计划,再到统计信息和验证,优化是一个不断迭代的过程:

  1. 根据业务查询模式,设计合理的索引(遵循等值在前、高选择性在前、覆盖索引等原则)。
  2. 执行EXPLAIN,检查执行计划是否符合预期。关注typekeyrowsExtra
  3. 如果优化器没选对索引,先ANALYZE TABLE更新统计信息。如果仍不对,检查是否有隐式类型转换、函数包裹索引列等失效原因。
  4. 在测试环境使用EXPLAIN ANALYZE验证真实执行情况,确认优化效果。
  5. 上线后持续监控慢查询日志,观察是否有新的慢查询出现。

这个闭环的核心思想是:​不要靠猜,要让数据库告诉你它需要什么​。执行计划就是数据库的“体检报告”,读懂它,你就能从被动救火变成主动预防。

小耶在手,SQL 不愁

还有什么想了解的,欢迎留言!小耶一定知无不言言无不尽……我们下次见~

http://www.jsqmd.com/news/1026073/

相关文章:

  • 2026 南宁回南天卫生间持续渗水维修推荐?实地测试 5 家本地防水老店 - 防水资讯
  • 实验任务6
  • 收藏不亏!2026最新AI大模型应用开发学习路线,小白/程序员转行高薪必备
  • 2026 温州汽车音响改装门店品牌测评盘点,本土十年老店无损改装方案优势梳理 - 资讯快报
  • 晋中漏水检测维修权威推荐:卫生间-厨房-阳台-屋顶天花板漏水维修:靠谱防水补漏公司团队TOP5推荐(2026最新深度调研实测榜单) - 即刻修防水
  • Ubuntu系统里面安装vscode
  • 嵌入式网络设备实战:Linux流量整形与JFFS2闪存文件系统部署
  • 二手手机水太深?这份靠谱的二手平台推荐,帮你避坑 - 资讯快报
  • 生产级多维聚合:金融场景下的可落地数据操作指南
  • Visual Studio 快捷键设计哲学与高效开发实践
  • C# NetworkStream 原理与高可靠网络编程实战
  • 2026流量转化导师中立测评榜单:企业全域获客选型干货指南 - 品牌2026推荐
  • 2026淘宝流量转化导师客观测评榜单|5大主流主体选型对比指南 - 品牌2026推荐
  • 2026年6月最新帝舵中国官方售后电话地址服务热线客服网点 - 资讯快报
  • 无糖茶饮料怎么选?王老吉原味0糖0卡植物本味更清爽 - 资讯快报
  • RoboTwin:5分钟掌握双臂机器人数字孪生平台终极指南
  • Overleaf到arXiv保姆级避坑指南:搞定.bbl文件与宏包缺失,一次上传成功
  • Python自动化办公:用docx库生成完美格式Word表格的保姆级教程
  • CARLA快速启动包:解决Ubuntu+GPU环境安装失败的核心方案
  • 数据库连接必须关闭吗?揭秘不释放连接的四重系统代价
  • 数独求解的三大技术路径:回溯、机器学习与量子计算实测对比
  • YSR态塞曼分裂抑制现象的量子特性与实验观测
  • S32K LINFlexD模块DMA配置与标识符过滤器实战指南
  • 2026年6月最新爱彼中国官方售后电话地址服务热线客服网点 - 资讯快报
  • 5个关键突破:让QuantStats成为你的量化投资决策引擎
  • 2026论文ai率过高怎么办?实测主流5款降ai率工具盘点 - 资讯快报
  • 2026年6月论文辅导机构口碑实测榜单:师资力量、学术成果与避坑全测评 - 刚达R
  • 2026京东流量转化导师客观测评榜单|商家全域转化选型指南 - 品牌2026推荐
  • 2026年6月最新宝珀中国官方售后电话地址及客户服务网点查询 - 资讯快报
  • ASP.NET网站IIS部署核心三关:扩展映射、通配符路由与权限配置