MySQL 的EXPLAIN 计划 type 字段详细说明

在 MySQL 的 EXPLAIN 执行计划中,type 字段表示查询的访问类型,即 MySQL 在查询时使用的数据检索方法。不同的 type 值表示不同的查询效率,通常 system 是最优的,而 ALL 是最差的。以下是这些 type 值的详细说明及其排序:

复制代码
system > const > eq_ref > ref > range > index > ALL

1. system(性能最优)

  • 说明

    • 该表只有一行记录(如 system 表,或者只有一条记录的 MyISAM 表)。
    • 相当于 const,但只适用于单行数据的情况。
  • 示例

    sql 复制代码
    EXPLAIN SELECT * FROM singleton_table;
  • 特点

    • 由于表只有一行,直接读取该行即可,不涉及索引扫描或全表扫描。
    • 访问代价极低。

2. const(常量查询)

  • 说明

    • 适用于 唯一索引(PRIMARY KEY 或 UNIQUE) 查询,并且查询条件是常量。
    • MySQL 仅需查询一次,就能获取数据。
    • 适用于 WHERE 子句中的主键或唯一索引等查询。
  • 示例

    sql 复制代码
    EXPLAIN SELECT * FROM employees WHERE emp_id = 100;
  • 特点

    • 查询结果最多返回一行。
    • 查询优化器会在编译阶段就确定查询结果,速度极快。
    • 适用于主键或唯一索引的等值查询。

3. eq_ref(唯一索引等值匹配)

  • 说明

    • eq_ref 用于 主键(PRIMARY KEY)或唯一索引(UNIQUE KEY) 的等值查询,通常出现在多表 JOIN 操作中。
    • 对于每一行来自主表的数据,子表最多只会返回一条匹配记录。
  • 示例

    sql 复制代码
    EXPLAIN 
    SELECT e.emp_id, d.dept_name 
    FROM employees e 
    JOIN departments d ON e.dept_id = d.dept_id;
  • 特点

    • 每次查询只返回一行数据 (因为 eq_ref 必须基于 PRIMARY KEYUNIQUE 索引)。
    • 查询优化效果非常好。
    • 常见于 JOIN 语句中,被连接表的主键或唯一索引用于匹配主表的字段。

4. ref(普通索引等值匹配)

  • 说明

    • ref 表示查询使用了非唯一索引(普通索引、非唯一的外键索引)。
    • 适用于非唯一索引或 JOIN 操作中的索引匹配,可能会返回 多行 数据。
  • 示例

    sql 复制代码
    EXPLAIN SELECT * FROM employees WHERE department_id = 5;
  • 特点

    • 使用索引查找,但不是唯一匹配(可能匹配多行)。
    • 常用于 JOIN 操作,或者在 WHERE 子句中使用非唯一索引的查询。

5. range(范围查询)

  • 说明

    • range 表示基于索引范围扫描,可以使用索引高效查找数据。
    • 常见的范围查询有 BETWEEN><IN 等。
  • 示例

    sql 复制代码
    EXPLAIN SELECT * FROM employees WHERE salary BETWEEN 5000 AND 10000;
  • 特点

    • 适用于索引列上的范围查询。
    • 扫描索引的部分数据,比全表扫描(ALL)高效。
    • 适用于 >, <, BETWEEN, IN() 等操作符。

6. index(全索引扫描)

  • 说明

    • index 表示 全索引扫描 ,相当于 ALL(全表扫描),但扫描的是索引而非数据行。
    • 适用于索引覆盖查询(即不需要回表查询)。
  • 示例

    sql 复制代码
    EXPLAIN SELECT idx_column FROM large_table;
  • 特点

    • 比全表扫描(ALL)稍快,因为索引通常比整个表小。
    • 不会使用 WHERE 过滤条件,会遍历整个索引。

7. ALL(全表扫描,性能最差)

  • 说明

    • ALL 表示 全表扫描,意味着 MySQL 需要遍历整个表的所有数据行。
    • 适用于无索引的查询,或者查询无法利用索引。
  • 示例

    sql 复制代码
    EXPLAIN SELECT * FROM employees WHERE name = 'John Doe';
  • 特点

    • 性能最差,因为需要扫描整张表。
    • MySQL 可能会自动使用 Using filesortUsing temporary 进行排序。
    • 如果 ALL 出现在大表查询中,通常需要优化索引

总结与排序

访问类型 适用情况 典型场景 速度
system 只有一行数据的表 读取单行数据 最快
const 主键或唯一索引等值查询 WHERE id = 1 极快
eq_ref 主键或唯一索引 JOIN 查询 JOIN ON primary_key 非常快
ref 非唯一索引等值查询 WHERE department_id = 5
range 范围查询 WHERE age BETWEEN 18 AND 30 中等
index 全索引扫描 SELECT idx_column FROM table 较慢
ALL 无索引查询或全表扫描 SELECT * FROM large_table 最慢

优化建议

  1. 避免 ALL(全表扫描)

    • 创建索引,提高查询效率。
    • 使用 EXPLAIN 分析执行计划,确认索引是否被使用。
  2. 优化 range(范围扫描)

    • 适当调整索引,避免 MySQL 过度扫描数据范围。
    • 使用 BETWEENIN() 查询时,确保索引列的数据分布合理。
  3. 提升 refeq_ref 查询

    • 使用外键关系,并确保 JOIN 语句涉及索引列。
    • 采用 覆盖索引,减少回表查询的次数。
  4. 优化 index(全索引扫描)

    • 避免 SELECT *,只查询必要字段,减少数据量。
    • 确保查询能利用索引,避免额外的 Using filesortUsing temporary

通过这些优化方法,可以减少数据库的负载,提高查询速度。

相关推荐
你过来啊你21 分钟前
Android用户鉴权实现方案深度分析
android·鉴权
水瓶_bxt24 分钟前
Centos安装HAProxy搭建Mysql高可用集群负载均衡
mysql·centos·负载均衡
♡喜欢做梦30 分钟前
【MySQL】深入浅出事务:保证数据一致性的核心武器
数据库·mysql
遇见你的雩风33 分钟前
MySQL的认识与基本操作
数据库·mysql
dblens 数据库管理和开发工具36 分钟前
MySQL新增字段DDL:锁表全解析、避坑指南与实战案例
数据库·mysql·dblens·dblens mysql·数据库连接管理
weixin_4196583136 分钟前
MySQL的基础操作
数据库·mysql
不辉放弃2 小时前
ZooKeeper 是什么?
数据库·大数据开发
Goona_2 小时前
拒绝SQL恐惧:用Python+pyqt打造任意Excel数据库查询系统
数据库·python·sql·excel·pyqt
kerli3 小时前
Android 嵌套滑动设计思想
android·客户端
Olrookie3 小时前
若依前后端分离版学习笔记(三)——表结构介绍
笔记·后端·mysql