当前位置: 首页 > article >正文

如何使用 MySQL 的 EXPLAIN 语句进行查询分析?

Explain 属性介绍

explain 主要用来 SQL 分析,它主要的属性详解如下:

  • id : 查询的执行顺序的标识符,值越大优先级越高。简单查询的 id 通常为 1,复杂查询(如包含子查询或 UNION)的 id 会有多个。
  • select_type (重要):查询的类型,如 SIMPLE(简单查询)、PRIMARY(主查询)、SUBQUERY(子查询)等。
  • table : 查询的数据表。
  • type (重要):访问类型,如 ALL(全表扫描)、index(索引扫描)、range(范围扫描)等。一般来说,性能从好到差的顺序是:const > eq_ref > ref > range > index > all
  • possible_keys : 可能用到的索引。
  • key (重要):实际用到的索引。
  • key_len : 用到索引的长度。
  • ref : 显示索引的哪一列被使用。
  • rows (重要):估计要扫描的行数,值越小越好。
  • filtered : 显示查询条件过滤掉的行的百分比。一个高百分比表示查询条件的选择性好。
  • Extra (重要):额外信息,如 Using index (表示使用覆盖索引)、Using where (表示使用 WHERE 条件进行过滤)、Using temporary (表示使用临时表)、Using filesort (表示需要额外的排序步骤)。

type 详解:

  • system:表示查询的表只有一行(系统表)。这是一个特殊的情况,不常见。
  • const:表示查询的表最多只有一行匹配结果。这通常发生在查询条件是 主键 主键 主键 唯一索引 唯一索引 唯一索引,并且是常量比较。
  • eq_ref:表示对于每个来自前一张表的行,MySQL 仅访问一次这个表。这通常发生在连接查询中使用主键或唯一索引的情况下。
  • ref:MySQL 使用非唯一索引扫描来查找行。查询条件使用的索引是非唯一的(如普通索引)。
  • range:表示 MySQL 会扫描表的一部分,而不是全部行。范围扫描通常出现在使用索引的范围查询中(如 BETWEEN 、 >, <, >=, <= )。
  • index:表示 MySQL 扫描索引中的所有行,而不是表中的所有行。即使索引列的值覆盖查询,也需要扫描整个索引。
  • all(性能最差):表示 MySQL 需要扫描表中的所有行,即全表扫描。通常出现在没有索引的查询条件中。

SQL 实战

  1. 建表语句
CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    department_id INT,
    salary DECIMAL(10, 2),
    hire_date DATE,
    INDEX (department_id)
);

  1. 填充数据
  • 脚本下载地址:https://restful.doublefenzhuan.me/public/bad6bf7e-3efa-48ff-9239-8b20bbb812e2-employee_data.sql
  1. 执行分析语句
EXPLAIN SELECT employee_id, first_name, last_name, salary
FROM employees
WHERE department_id = 5 AND salary BETWEEN 50000 AND 100000
ORDER BY salary DESC;
  • 执行结果:
    在这里插入图片描述

分析 EXPLAIN 结果的思路和过程:

  1. 首先看 type 列:
  • ref 表示使用非唯一索引扫描,这个效率还可以,但不是最优的 const
  • 如果看到 ALL 就说明全表扫描,需要立即优化
  • 最好是能看到 const, eq_ref 这样的类型
  1. 分析 rows 列:
  • 当前显示 482 行,需要评估这个数字是否合理
  • 如果 rows 数值过大,说明扫描的行数太多,需要考虑优化
  1. 检查 Extra 列:
  • 出现 “Using where” 说明需要在服务器层进行数据过滤
  • “Using filesort” 表示需要额外的排序操作,应该尽量避免
  • “Using index” 表示使用了覆盖索引,这是较好的情况

优化方案

针对 type=ref 的优化:

  • 当前使用的是单列索引(department_id)
  • 可以创建联合索引: (department_id, salary)
  • 因为查询同时用到这两个字段作为条件

ALTER TABLE employees ADD INDEX idx_dept_salary (department_id, salary);

执行

在这里插入图片描述

分析优化第一次后的结果

  1. 变化对比:
  • type 从 ref 变成了 range:
    • ref 类型特点:表示使用非唯一索引的等值查询,只用到了 department_id = 5 这个等值条件。
    • range 类型特点:表示索引范围扫描,发生在使用 >, <, BETWEEN, IN, LIKE 等操作符时(这里是因为 salary BETWEEN 50000 AND 100000 条件)
  • rows 从 482 减少到 241
  • key 使用了新建的 idx_dept_salary 索引
  • Extra 显示 “Using index condition; Backward index scan”
  1. 优化效果分析:
  • 扫描行数减少了约50%,说明索引效果不错
  • range 类型表示范围扫描,这是因为 salary BETWEEN 条件
  • Backward index scan 说明在处理 ORDER BY salary DESC

http://www.kler.cn/a/518659.html

相关文章:

  • 壁纸设计过程中如何增加氛围感
  • 【ComfyUI专栏】ComfyUI 部署Kolors
  • FastExcel的使用
  • HBase-2.5.10 伪分布式环境搭建【Mac】
  • 【开源免费】基于Vue和SpringBoot的医院资源管理系统(附论文)
  • 微信小程序-点餐(美食屋)02开发实践
  • 数据结构测试题2
  • day1代码练习
  • 在 DevOps 实践中,如何构建自动化的持续集成和持续交付(CI/CD)管道,以提高开发和测试效率?
  • 浅谈Redis
  • c语言分支和循环
  • ros动态调参界面的修改
  • Linux内核中IPoIB驱动模块的初始化与实现
  • 什么是COLLATE排序规则?
  • WPF基础 | WPF 基础概念全解析:布局、控件与事件
  • 2025-01-22 Unity Editor 1 —— MenuItem 入门
  • 2025美赛数学建模MCM/ICM选题建议与分析,思路+模型+代码
  • 寒假1.23
  • springboot图书馆管理系统前后端分离版本
  • 程序员转型测试:解锁漏洞挖掘新旅程
  • Ubuntu终端CTRL+S被锁定后解锁快捷键
  • 【音视频处理】FFmpeg for Windows 安装教程
  • PHP explode函数基本用法
  • 数巅科技连续中标大模型项目 持续助力央国企数智化升级
  • 【机器学习】使用pytorch框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测
  • 【机器学习】使用scikit-learn中的KNN包实现对鸢尾花数据集或者自定义数据集的的预测