位置:首页 > SQL > SQL SELECT查询性能问题排查:如何通过执行计划快速定位

SQL SELECT查询性能问题排查:如何通过执行计划快速定位

时间:2026-08-17  |  作者:云端旅人  |  阅读:0

看执行计划时,type、key、rows 这三列一定要盯紧:type 一旦出现 ALL,基本就是在做全表扫描;key 如果是 NULL,说明索引根本没派上用场;rows 要是已经接近总行数,往往意味着索引失效了,或者索引选择性本身就不理想。

SQL SELECT查询如何通过执行计划定位性能问题?

EXPLAIN 输出里哪几列必须盯死?

EXPLAIN 结果,不能只扫一眼就完事。

重点盯三列:typekeyrows。这三列会直接暴露查询是否走索引、走哪个索引、扫描多少行。

  • type 值是 ALL?基本等于全表扫描。10 万行表查一次就得遍历全部,立刻要加索引。
  • keyNULL?说明没用上任何索引。哪怕你建了索引,也可能因为 WHERE 里写了 UPPER(email)age + 1 = 25 导致失效。
  • rows 数远大于实际返回行数,比如查 1 条却预估扫 8 万行?统计信息可能过期,得跑 ANALYZE TABLE users

为什么 type=range 还很慢?

range 乍一看确实比 ALL 更像“优化过”的方案,但不要太早下结论。

它只是说明数据库走了索引范围扫描,并不等于执行效率就一定高。

比如 WHERE created_at > '2020-01-01' 这样的条件,放在千万级大表里,照样可能一口气扫出几十万行。

重点排查这几项

  • 检查 rows 值是否过大。如果大,说明索引选择性差,得换字段或加复合索引。
  • 确认是否覆盖查询:SELECT 的字段是否全在索引里?否则会回表,Extra 里出现 Using where 且没 Using index 就是信号。
  • 避免在 range 条件字段上做函数操作。DATE(created_at) = '2024-01-01' 会让索引完全失效。

JSON 格式执行计划比表格更有用吗?

对简单单表查询,表格够用。

但涉及 JOIN、子查询、UNION 时,EXPLAIN FORMAT=JSON 才能看清嵌套结构和各层的预估成本。

重点看哪些信息

  • "cost_info" 下的 "query_cost",数值越大越耗资源。
  • "nested_loop""hash_join" 节点,确认连接顺序是否合理。一般应是小表驱动大表。
  • 留意 "filtered" 字段。若远低于 100%,说明 WHERE 条件过滤效果差,可能需要调整索引顺序或拆分条件。

执行计划“看着没问题”,查询还是慢怎么办?

常见陷阱,是把执行计划当成静态快照,忽略了运行时干扰。

常见排查方向

  • 锁等待:SHOW PROCESSLIST 查是否有 StateWaiting for table metadata lockLocked 的线程。
  • 临时表/文件排序:Extra 出现 Using temporaryUsing filesort,说明内存不够或 ORDER BY 字段没索引。
  • 参数绑定导致计划复用错误:同一条 SQL 用不同参数执行,优化器可能复用上次低效计划,可加 /*+ RECOMPILE */(SQL Server)或清缓存(MySQL 用 FLUSH TABLES)验证。

执行计划只是起点,不是终点。

真正卡住的地方,往往藏在 rows 预估偏差、锁状态、内存配置这些“看不见”的环节里。

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多