怎么检查是否用到索引
检查是否用到索引概述
- 目标:
- 确定 SQL 查询是否使用了索引,以评估性能并优化慢查询。
- 主要方法:
- EXPLAIN 分析:查看执行计划,检查索引使用情况。
- 慢查询日志:定位未用索引的查询。
- SHOW PROFILE:分析查询资源消耗。
- 性能监控工具:如
INFORMATION_SCHEMA
或第三方工具。
核心点
- EXPLAIN 是最直接的检查手段,关注
key
和type
。
1. 使用 EXPLAIN 分析
(1) 基本用法
- 命令:
EXPLAIN SELECT * FROM user WHERE age > 20;
- 作用:
- 显示查询的执行计划,包括是否使用索引、扫描行数等。
(2) 关键字段
- key:
- 表示实际使用的索引。
NULL
:未使用索引。- 例:
key: idx_age
表示用了idx_age
索引。 - possible_keys:
- 可能使用的索引,若为空,说明无可用索引。
- type:
- 访问类型,从好到差:
const
、eq_ref
:高效,精准匹配。ref
、range
:用索引,较优。index
:扫描整个索引。ALL
:全表扫描,未用索引。
- rows:
- 预计扫描行数,值大可能未用索引或索引效率低。
- Extra:
- 额外信息:
Using index
:覆盖索引,未回表。Using where
:过滤条件,未必用索引。Using filesort
、Using temporary
:未用索引排序或临时表。
(3) 示例
- 无索引:
EXPLAIN SELECT * FROM user WHERE age > 20;
id | select_type | table | type | possible_keys | key | rows | Extra
1 | SIMPLE | user | ALL | NULL | NULL | 1000 | Using where
- 分析:
type: ALL
,key: NULL
,全表扫描,未用索引。 - 有索引:
CREATE INDEX idx_age ON user(age);
EXPLAIN SELECT * FROM user WHERE age > 20;
id | select_type | table | type | possible_keys | key | rows | Extra
1 | SIMPLE | user | range | idx_age | idx_age | 100 | Using where
- 分析:
type: range
,key: idx_age
,使用了索引。
2. 慢查询日志
(1) 配置
- 启用:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1; -- 阈值 1 秒
SET GLOBAL log_queries_not_using_indexes = 'ON'; -- 记录未用索引查询
- 日志内容:
- 包含执行时间、SQL 语句、扫描行数等。
- 示例:
# Query_time: 2.5 Rows_examined: 1000000
SELECT * FROM user WHERE age > 20;
- 分析:高
Rows_examined
提示可能未用索引。
(2) 分析工具
- mysqldumpslow:
mysqldumpslow -t 10 /var/log/mysql/slow.log
- 显示前 10 条慢查询。
- pt-query-digest:
- 更详细,统计未用索引比例。
3. 使用 SHOW PROFILE
- 作用:
- 分析查询的资源消耗,间接推断索引使用。
- 启用:
SET profiling = 1;
SELECT * FROM user WHERE age > 20;
SHOW PROFILES;
SHOW PROFILE FOR QUERY 1;
- 分析:
- 若
Sending data
时间长,可能全表扫描。 - 例:
Status | Duration
Sending data | 0.250
- 高耗时提示未用索引。
4. 性能监控工具
(1) INFORMATION_SCHEMA
- 查询:
SELECT * FROM information_schema.STATISTICS WHERE TABLE_NAME = 'user';
- 查看索引列表,检查是否可用。
- 全局统计:
SHOW GLOBAL STATUS LIKE 'Handler_read%';
Handler_read_rnd_next
高,说明全表扫描多。
(2) 第三方工具
- MySQL Workbench:可视化执行计划。
- Percona Toolkit:
pt-index-usage
分析索引使用率。 - Prometheus + Grafana:监控慢查询和索引命中。
5. 注意事项
(1) 索引失效场景
- 函数/运算:
SELECT * FROM user WHERE YEAR(create_time) = 2025;
- 索引失效,需改写:
SELECT * FROM user WHERE create_time >= '2025-01-01';
- 类型不匹配:
- 例:
VARCHAR
列用数字比较。 - OR 条件:
- 例:
WHERE age > 20 OR name = 'Alice'
可能不走索引。 - 非最左前缀:
- 复合索引
idx_age_name
,查询name
不走索引。
(2) 覆盖索引
- 若查询字段全在索引中,无需回表:
EXPLAIN SELECT age FROM user WHERE age = 25;
Extra: Using index
确认高效。
(3) 验证优化
- 加索引后重新 EXPLAIN:
CREATE INDEX idx_age ON user(age);
EXPLAIN SELECT * FROM user WHERE age > 20;
- 确认
key
和type
改善。
6. 延伸与面试角度
- 与慢查询:
- 未用索引是慢查询主因,EXPLAIN 优先。
- 实际应用:
- 电商:优化商品查询。
- 日志:加速时间范围查询。
- 工具:
EXPLAIN ANALYZE
(MySQL 8.0+)提供实际耗时。- 面试点:
- 问“检查”时,提 EXPLAIN 字段。
- 问“失效”时,提函数和类型。
总结
检查 MySQL 是否用到索引主要靠 EXPLAIN(关注 key
、type
),辅以慢查询日志、SHOW PROFILE 和监控工具。需注意索引失效场景并验证优化效果。面试时,可提示例或分析步骤,展示实战能力。