MySQL索引EXPLAIN执行计划type类型解析

MySQL索引EXPLAIN执行计划type类型解析

在 MySQL 中,使用 EXPLAIN 命令可以查看 SQL 查询的执行计划,其中 type 字段表示 MySQL 在查询时访问表的方式(即连接类型或访问类型)。不同的 type 值反映了查询的效率和扫描范围。本文将详细解析 type 的各种取值、它们的效率排序,以及 typerange 的适用场景。

一、type 的各种类型及效率排序

以下是 EXPLAIN 输出中 type 字段可能出现的取值,从效率最高到最低排序:

  1. system

    • 描述: 表只有一行数据(通常是系统表)。这是最快的访问类型。
    • 效率: 最高,因为只需要读取一行数据。
    • 场景: 常用于 MyISAM 引擎的系统表,InnoDB 很少出现。
  2. const

    • 描述 : 通过主键或唯一索引查找,且最多返回一行数据。查询条件是常量(例如 WHERE id = 5)。
    • 效率 : 极高,仅次于 system,因为直接定位到单行。
    • 场景: 主键查询或唯一索引查询。
  3. eq_ref

    • 描述: 在联表查询中,通过主键或唯一非空索引进行等值匹配,每行只匹配一行数据。
    • 效率: 非常高,逐行精确匹配。
    • 场景 : 例如 SELECT * FROM t1 JOIN t2 ON t1.id = t2.id,其中 t2.id 是主键或唯一索引。
  4. ref

    • 描述: 通过非唯一索引或唯一索引的前缀进行等值匹配,可能返回多行数据。
    • 效率: 中等偏高,依赖索引选择性。
    • 场景 : 例如 WHERE name = 'Alice'name 是普通索引。
  5. range

    • 描述: 通过索引进行范围扫描,返回符合条件的行。
    • 效率: 中等,优于全表扫描但不如等值匹配。
    • 场景 : 范围查询,如 WHERE id > 10 AND id < 20
  6. index

    • 描述: 全索引扫描,扫描整个索引树而不是表数据。
    • 效率: 中等偏低,比全表扫描稍好。
    • 场景 : 查询只需要索引列即可满足,例如 SELECT indexed_col FROM table
  7. ALL

    • 描述: 全表扫描,逐行检查每一行数据。
    • 效率: 最低,性能最差。
    • 场景: 无索引可用或索引未被优化器选择。

效率排序总结

system > const > eq_ref > ref > range > index > ALL

二、typerange 的情况

typerange 时,说明 MySQL 使用了索引进行范围扫描。以下是常见的触发 range 类型的 SQL 查询场景:

1. 范围查询

最典型的情况是使用范围操作符,例如:

  • ><>=<=

  • BETWEEN ... AND ...

  • 示例:

    sql 复制代码
    SELECT * FROM users WHERE age BETWEEN 18 AND 30;
    SELECT * FROM orders WHERE order_date > '2025-01-01';

2. IN 查询(部分情况)

当使用 IN 指定多个离散值时,如果值是连续的或者优化器认为可以转为范围扫描,type 可能为 range

  • 示例:

    sql 复制代码
    SELECT * FROM products WHERE id IN (1, 2, 3, 4, 5);
    • 注意:如果 IN 的值不连续且数量较多,优化器可能退化为 ref 或其他类型。

3. LIKE 前缀匹配(特定情况)

当使用 LIKE 进行前缀匹配且列有索引时,可能触发 range

  • 示例:

    sql 复制代码
    SELECT * FROM employees WHERE name LIKE 'A%';
    • 注意:如果 LIKE 使用通配符开头(如 %abc),则无法使用索引,退化为 ALL

4. 除了范围查询外的其他情况

除了显式的范围查询,某些条件下优化器可能将查询优化为范围扫描:

  • 多列索引的部分范围匹配
    对于复合索引 (col1, col2),如果 WHERE col1 = 10 AND col2 > 5,对 col2 的范围条件会导致 range
  • 排序或分组优化
    如果查询涉及 ORDER BYGROUP BY,且优化器选择索引范围扫描来避免额外排序,可能是 range

示例分析

假设表 users 有索引 idx_ageage 列上:

sql 复制代码
EXPLAIN SELECT * FROM users WHERE age > 20 AND age < 30;

输出:

  • type: range
  • key: idx_age
  • 原因:使用了索引 idx_age 进行范围扫描。

三、总结

  • type 类型效率 :从 systemALL,效率逐步降低。优化 SQL 时,尽量让 type 靠近左侧(如 consteq_ref)。
  • range 的触发条件 :主要由范围查询触发(如 ><BETWEEN),此外 IN 和某些 LIKE 查询也可能导致 range
  • 优化建议 :为查询条件创建合适的索引,避免全表扫描 (ALL),并尽量使用等值匹配而非范围扫描以提升性能。

通过理解 EXPLAINtype,我们可以更好地分析和优化 SQL 查询,提升数据库性能。

相关推荐
凌览9 分钟前
你记得住密码吗?四款密码管理产品推荐
前端·后端·面试
西岭千秋雪_18 分钟前
Sentinel核心源码分析(上)
spring boot·分布式·后端·spring cloud·微服务·sentinel
CodeFans22 分钟前
如何理解Java中的 stream ?
后端
bobz96524 分钟前
ipsec route table 220 有什么用?
后端
清风孤月残酌28 分钟前
Java中的锁,锁的究竟是什么?
后端·面试
程序员爱钓鱼33 分钟前
用Go写一个《植物大战僵尸》小游戏:支持鼠标放僵尸、胜利失败判定!
后端·游戏·go
lamdaxu34 分钟前
微服务调用组件Feign实战
后端
零零壹1137 分钟前
Swagger 中的 x-nullable 是什么意思?
前端·后端·面试
程序员勋勋11 小时前
【GoLang】etcd初始化客户端时不会返回错误怎么办
后端·golang·etcd
Aska_Lv1 小时前
生产问题讨论---4C8G的机器,各项系统指标,什么范围算是正常
后端·面试·架构