MySQL创建了一个索引表,如何来验证这个索引表是否使用了呢?
1. 使用 EXPLAIN 分析查询执行计划
在 SQL 查询前添加 EXPLAIN 关键字,查看 MySQL 优化器是否选择了你的索引。
示例:
sql
EXPLAIN SELECT * FROM `db`

关键输出字段:
- type: 访问类型:const(唯一索引)、ref(非唯一索引)、range(范围索引)、ALL(全表扫描)
- possible_keys: 可能使用的索引列表(显示你的索引名则表示优化器认为可用)
- key: 实际使用的索引(如果显示你的索引名,则索引被使用)
- rows: 预估扫描的行数(索引生效时此值会显著降低)
- Extra: 附加信息:Using index 表示索引覆盖,无需回表
关键点:若 key 列显示你的索引名称(如 idx_email),则索引被使用。
2. 查看索引统计信息
通过 SHOW INDEX 命令查看索引的详细信息,包括基数(Cardinality)。
示例:
sql
SHOW INDEX FROM `db`;

关键点:
-
Cardinality:索引的唯一性估计值(越高越好)。如果值接近表的总行数,说明索引选择性高。
-
若 Cardinality 值过低,优化器可能认为全表扫描更快,导致索引未被使用。
3. 强制使用索引(测试验证)
通过 FORCE INDEX 强制查询使用索引,对比性能差异。
示例:
sql
-- 强制使用索引
SELECT * FROM users FORCE INDEX (idx_email) WHERE email = '[email protected]';
-- 正常查询(不强制)
SELECT * FROM users WHERE email = '[email protected]';
对比结果:
-
如果强制使用索引后查询速度显著提升,说明优化器未正确选择索引。
-
如果性能无变化,可能索引未被有效利用或数据量较小。
4. 监控慢查询日志
通过慢查询日志判断是否因索引缺失导致查询缓慢。
步骤:
sql
-- 开启慢查询日志:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2; -- 超过2秒的查询记录
-- 分析慢查询日志:
SHOW VARIABLES LIKE 'slow_query_log_file';
打开日志文件,查找未使用索引的查询:
sql
# Query_time: 5.123456 Lock_time: 0.001234 Rows_sent: 1 Rows_examined: 100000
SELECT * FROM users WHERE email = '[email protected]';
关键点:Rows_examined 远大于 Rows_sent 时,可能未使用索引。
5. 更新统计信息
优化器依赖统计信息选择索引。若统计信息过期,可能导致索引未被使用。
手动更新统计信息:
sql
ANALYZE TABLE users;
6. 常见索引未使用的原因及解决方案
原因 | 验证方法 | 解决方案 |
---|---|---|
查询条件不匹配索引列 | 检查 WHERE 或 JOIN 条件是否匹配索引列 | 调整查询条件或重建索引 |
索引选择性低 | SHOW INDEX 查看 Cardinality 值 | 对高选择性列建索引(如唯一字段) |
隐式类型转换 | 检查查询条件类型是否与索引列一致 | 确保查询条件与索引列类型一致 |
函数或表达式操作列 | 查看 WHERE 子句是否包含函数 | 创建函数索引(MySQL 8.0+ 支持虚拟列) |
优化器误判 | 强制使用索引对比性能 | 优化表统计信息或调整查询 |
验证流程图
总结
通过 EXPLAIN 分析执行计划、SHOW INDEX 查看统计信息、强制索引测试和慢查询日志监控,可以明确验证 MySQL 索引是否被使用。若索引未被使用,需结合优化策略(如更新统计信息、调整查询或重建索引)解决问题。