Skip to content

怎么检查是否用到索引

检查是否用到索引概述

  • 目标
  • 确定 SQL 查询是否使用了索引,以评估性能并优化慢查询。
  • 主要方法
  • EXPLAIN 分析:查看执行计划,检查索引使用情况。
  • 慢查询日志:定位未用索引的查询。
  • SHOW PROFILE:分析查询资源消耗。
  • 性能监控工具:如 INFORMATION_SCHEMA 或第三方工具。

核心点

  • EXPLAIN 是最直接的检查手段,关注 keytype

1. 使用 EXPLAIN 分析

(1) 基本用法

  • 命令
EXPLAIN SELECT * FROM user WHERE age > 20;
  • 作用
  • 显示查询的执行计划,包括是否使用索引、扫描行数等。

(2) 关键字段

  • key
  • 表示实际使用的索引。
  • NULL:未使用索引。
  • 例:key: idx_age 表示用了 idx_age 索引。
  • possible_keys
  • 可能使用的索引,若为空,说明无可用索引。
  • type
  • 访问类型,从好到差:
    • consteq_ref:高效,精准匹配。
    • refrange:用索引,较优。
    • index:扫描整个索引。
    • ALL:全表扫描,未用索引。
  • rows
  • 预计扫描行数,值大可能未用索引或索引效率低。
  • Extra
  • 额外信息:
    • Using index:覆盖索引,未回表。
    • Using where:过滤条件,未必用索引。
    • Using filesortUsing 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: ALLkey: 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: rangekey: 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 Toolkitpt-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;
  • 确认 keytype 改善。

6. 延伸与面试角度

  • 与慢查询
  • 未用索引是慢查询主因,EXPLAIN 优先。
  • 实际应用
  • 电商:优化商品查询。
  • 日志:加速时间范围查询。
  • 工具
  • EXPLAIN ANALYZE(MySQL 8.0+)提供实际耗时。
  • 面试点
  • 问“检查”时,提 EXPLAIN 字段。
  • 问“失效”时,提函数和类型。

总结

检查 MySQL 是否用到索引主要靠 EXPLAIN(关注 keytype),辅以慢查询日志、SHOW PROFILE 和监控工具。需注意索引失效场景并验证优化效果。面试时,可提示例或分析步骤,展示实战能力。