SQL如何判断是否走索引_索引命中分析方法

6次阅读

判断sql是否走索引关键看执行时是否利用索引结构定位数据而非全表扫描,需结合执行计划(如mysql的explain中type、key、extra字段)、状态变量(如handler_read_key占比)及慢日志分析索引失效原因。

SQL如何判断是否走索引_索引命中分析方法

判断SQL是否走索引,核心是看执行时是否真正利用了索引结构进行数据定位,而不是全表扫描。不能只看“有没有建索引”,而要看“运行时有没有用上”。常用方法分三类:查执行计划、看状态变量、结合日志分析。

看执行计划(最直接有效)

在MySQL中用 EXPLAIN,在SQL Server中用“显示实际执行计划”(Ctrl+M 或 SSMS 图形界面)。

  • MySQL 的关键字段
    type:值为 consteq_refrefrange 表示走了索引;ALLindex 说明是全表或全索引扫描,效率低。
    key:显示实际使用的索引名,为 NULL 即未命中索引。
    Extra:出现 using filesortUsing temporary 往往意味着排序/分组没走索引;Using index 表示覆盖索引,性能更优。
  • SQL Server 的关键信号
    • 执行计划中出现 Index Seek(索引查找)是理想情况;
    • 出现 Index Scantable Scan 表示未精准定位,可能因缺失前导列、条件不匹配或统计信息过期。

查全局状态变量(评估整体趋势)

适用于快速判断数据库层面的索引使用健康度,但无法定位具体SQL。

  • MySQL 常用指标
    • 运行 SHOW STATUS LIKE 'Handler_read%';
    • 关注 Handler_read_key(索引查找次数)和 Handler_read_rnd_next(全表扫描行读取次数)
    • 索引命中率粗略估算:
    (Handler_read_key) / (Handler_read_key + Handler_read_rnd_next) * 100%
    低于 90% 就值得深入排查。
  • InnoDB 缓冲池命中率(间接反映索引有效性):
    • 查询:
    select (1 - (VARIABLE_VALUE / (SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests'))) * 100 AS 'Hit Rate' FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = 'Innodb_buffer_pool_reads';
    • 高于 99% 较健康;若偏低,可能是热数据没进缓存,或大量查询绕过了索引。

结合慢查询日志与条件细节(定位问题根源)

命中与否,往往取决于查询写法和索引设计是否匹配。

  • 常见导致索引失效的情况
    • WHERE 中对索引列使用函数或计算,如 WHERE YEAR(create_time) = 2025 → 改为 WHERE create_time >= '2025-01-01' AND create_time <br> • 模糊查询左模糊:<code>LIKE '%abc' 无法用B树索引;LIKE 'abc%' 可以。
    • 复合索引未满足最左前缀原则,例如索引是 (a, b, c),但查询只用了 b = ?c = ?
    • 使用 OR 且部分条件无索引,可能导致整个条件放弃索引。
  • 辅助验证手段
    • 开启慢查询日志:SET GLOBAL slow_query_log = ON; SET GLOBAL long_query_time = 1;
    • 对慢SQL逐条 EXPLAIN,重点关注 typekey 字段变化。
    • 在测试环境用 FORCE INDEX(MySQL)或 WITH (INDEX=...)(SQL Server)临时强制走某索引,验证效果。

索引命中不是黑盒结果,而是查询逻辑、索引结构、数据分布和优化器决策共同作用的表现。动手看执行计划,再比对条件写法,基本就能说清“为什么走”或“为什么没走”。

text=ZqhQzanResources