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 KEY 或 UNIQUE 索引)。
    • 查询优化效果非常好。
    • 常见于 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 filesort 或 Using 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 过度扫描数据范围。
    • 使用 BETWEEN 或 IN() 查询时,确保索引列的数据分布合理。
  3. 提升 ref 和 eq_ref 查询:

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

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

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

相关推荐
软件派4 小时前
生产动态数据智能风控:阈值判别、趋势预测、异常识别算法工程落地实战
前端·数据库·算法
ss27311 小时前
PostgreSQL常见索引问题与解决方案
数据库·postgresql
小徐不徐说11 小时前
序列化与反序列化:把 C++ 对象可靠地保存下来
开发语言·数据库·c++·php
瀚高PG实验室13 小时前
发布端逻辑复制槽消失
数据库·postgresql·瀚高数据库
ss27313 小时前
PostgreSQL慢查询定位与优化
数据库·postgresql
香蕉大香蕉(06敬畏市场)14 小时前
MySQL 单点详解(07)
java·数据库·mysql·ai·博客·八股
smilejingwei15 小时前
TRAE 插件上新 | SQLazy:让 AI 写出可信复杂 SQL
数据库·人工智能·sql
我要见SA姐115 小时前
GitHub Actions 自动化:5 个真实运维提效案例
运维·数据库·机器学习·oracle·回归
传奇开心果编程15 小时前
【Jetpack Compose娓娓道来】第29课:状态容器与UI事件建模——把“散装状态”变成“可穷举的契约”
android·kotlin·移动开发·android jetpack·ui框架·开发范式·声明式ui