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

判断SQL是否走索引,核心是看执行时是否真正利用了索引结构进行数据定位,而不是全表扫描。不能只看“有没有建索引”,而要看“运行时有没有用上”。常用方法分三类:查执行计划、看状态变量、结合日志分析。
看执行计划(最直接有效)
在MySQL中用 EXPLAIN,在SQL Server中用“显示实际执行计划”(Ctrl+M 或 SSMS 图形界面)。
-
MySQL 的关键字段:
• type:值为const、eq_ref、ref、range表示走了索引;ALL或index说明是全表或全索引扫描,效率低。
• key:显示实际使用的索引名,为NULL即未命中索引。
• Extra:出现Using filesort或Using temporary往往意味着排序/分组没走索引;Using index表示覆盖索引,性能更优。 -
SQL Server 的关键信号:
• 执行计划中出现 Index Seek(索引查找)是理想情况;
• 出现 Index Scan 或 Table 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,重点关注type和key字段变化。
• 在测试环境用FORCE INDEX(MySQL)或WITH (INDEX=...)(SQL Server)临时强制走某索引,验证效果。
索引命中不是黑盒结果,而是查询逻辑、索引结构、数据分布和优化器决策共同作用的表现。动手看执行计划,再比对条件写法,基本就能说清“为什么走”或“为什么没走”。










