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 查询,提升数据库性能。

相关推荐
uzong20 分钟前
软件架构指南 Software Architecture Guide
后端
又是忙碌的一天20 分钟前
SpringBoot 创建及登录、拦截器
java·spring boot·后端
勇哥java实战分享1 小时前
短信平台 Pro 版本 ,比开源版本更强大
后端
学历真的很重要1 小时前
LangChain V1.0 Context Engineering(上下文工程)详细指南
人工智能·后端·学习·语言模型·面试·职场和发展·langchain
计算机毕设VX:Fegn08951 小时前
计算机毕业设计|基于springboot + vue二手家电管理系统(源码+数据库+文档)
vue.js·spring boot·后端·课程设计
上进小菜猪2 小时前
基于 YOLOv8 的智能杂草检测识别实战 [目标检测完整源码]
后端
韩师傅3 小时前
前端开发消亡史:AI也无法掩盖没有设计创造力的真相
前端·人工智能·后端
栈与堆3 小时前
LeetCode-1-两数之和
java·数据结构·后端·python·算法·leetcode·rust
superman超哥3 小时前
双端迭代器(DoubleEndedIterator):Rust双向遍历的优雅实现
开发语言·后端·rust·双端迭代器·rust双向遍历
1二山似3 小时前
crmeb多商户启动swoole时报‘加密文件丢失’
后端·swoole