mysql如何判断是否使用索引_mysql索引使用机制

2次阅读

判断mysql是否走索引的唯一可靠方法是查看explain执行计划,重点关注type、key、rows和extra四列;常见索引失效原因包括隐式类型转换、对索引列使用函数、前置通配符模糊查询、联合索引未遵循最左前缀及or混用不同列索引。

mysql如何判断是否使用索引_mysql索引使用机制

直接看 EXPLAIN 输出,这是唯一靠谱的方法

MySQL 是否走索引,不靠猜、不靠日志、不靠经验判断,只看 EXPLAIN 的执行计划。加在查询前就能立刻看到优化器的真实选择:

EXPLAIN SELECT * FROM users WHERE email = 'a@b.com';

重点关注四列:
type:值为 ALL 就是全表扫描,基本没走索引;refrange 或更优(如 const)才说明用了索引
key:非 NULL 才表示实际命中了某个索引,否则就是“有索引但没用上”
rows:预估扫描行数,远小于总行数(比如 100 行 vs 表里 100 万行)才是有效索引
Extra:出现 using index 是覆盖索引,性能最好;出现 Using filesortUsing temporary 往往意味着排序/分组没走索引

为什么明明建了索引却显示 key: NULL

常见原因不是索引不存在,而是被优化器主动绕过了。最典型的情况:
隐式类型转换phoneVARCHAR,但写成 WHERE phone = 13800138000,MySQL 会把字段转成数字比较,索引失效
• 对索引列用函数:WHERE YEAR(create_time) = 2023WHERE UPPER(name) = 'AliCE'
• 模糊查询以通配符开头:WHERE name LIKE '%li%',无法利用 B+ 树有序性
• 联合索引未遵循最左前缀:INDEX(a, b, c),但只查 WHERE b = 1WHERE c = 1
OR 条件混用不同列:WHERE a = 1 OR b = 2,若只有单列索引,通常两个都用不上

别只信 EXPLAIN,还要验证真实使用频次

EXPLAIN 是“理论上怎么走”,而生产中更关键的是“实际上有没有被用”。MySQL 5.6+ 提供了运行时统计:
• 查当前哪些索引真被访问过:

SELECT object_name AS table_name, index_name, count_fetch AS times_used FROM performance_schema.table_io_waits_summary_by_index_usage WHERE object_schema = 'your_db' AND count_fetch > 0 ORDER BY count_fetch DESC;

• 长期为 0 的索引,大概率是冗余或废弃的,可考虑删除
• 注意:需确保 performance_schema 已启用,且相关 instrument(如 table/io/table/sql/handler)处于 ENABLED 状态
sys.schema_unused_indexes(MySQL 5.7+)也能快速列出疑似未使用的索引

小数据量下 EXPLAIN 显示 ALL 不代表有问题

MySQL 优化器会估算成本,如果表只有几百行,它可能认为全表扫描比走索引再回表更快——这是合理决策,不是 bug
• 别在测试环境用空表或 10 行数据验证索引效果
• 真实判断必须基于接近生产的数据量(至少几千行以上)
• 若线上大表仍出现 type: ALL,优先检查 SHOW INDEX FROM table_name 确认索引存在、字段顺序正确、没有拼写错误
• 必要时可用 FORCE INDEX 强制走某索引做对比:

SELECT * FROM users FORCE INDEX (idx_email) WHERE email = 'a@b.com';

但仅限诊断,不可长期依赖

text=ZqhQzanResources