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

MySQL的explain使用

在 MySQL 中,EXPLAIN 是一个非常重要的性能分析工具,用来查看 SQL 语句的执行计划,判断其执行效率,是否使用索引,是否存在全表扫描等问题。

✅ EXPLAIN 用法概览
基本语法:
EXPLAIN SELECT * FROM your_table WHERE some_column = 'value';
或者使用更详细的格式(MySQL 5.7+ 推荐):

EXPLAIN FORMAT=JSON SELECT ...
🔍 EXPLAIN 输出字段说明(普通模式)
示例:

EXPLAIN SELECT * FROM employees WHERE department_id = 10;
输出示例:

id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE employees NULL ref dept_idx dept_idx 4 const 100 100.00 Using where
字段解释:
字段 含义
id 查询中每个 SELECT 子句的标识符。多表查询时会有多个。
select_type 查询类型:SIMPLE(简单查询)、PRIMARY、SUBQUERY、DERIVED(派生表)等
table 正在访问的表名
partitions 使用的分区(如果有)
type 连接类型,越靠近 const,性能越好(从好到差:system > const > eq_ref > ref > range > index > ALL)
possible_keys 查询可能用到的索引
key 实际使用的索引
key_len 索引使用的字节长度
ref 哪一列或常量与 key 一起使用
rows MySQL 估计要读取的行数
filtered 行的过滤比例(百分比)
Extra 额外信息,如 Using where、Using index、Using temporary、Using filesort 等
📌 示例对比
🔴 示例 1:未使用索引(全表扫描)
EXPLAIN SELECT * FROM employees WHERE last_name = 'Smith';
如果 last_name 没有索引,type 是 ALL,表示全表扫描:

type: ALL
possible_keys: NULL
key: NULL
rows: 100000
Extra: Using where
✅ 示例 2:使用索引(条件列有索引)
-- 给 last_name 创建索引
CREATE INDEX idx_lastname ON employees(last_name);

-- 再执行查询
EXPLAIN SELECT * FROM employees WHERE last_name = 'Smith';
输出:

type: ref
possible_keys: idx_lastname
key: idx_lastname
rows: 10
Extra: Using where
✅ 示例 3:使用覆盖索引(Extra 中出现 Using index)
EXPLAIN SELECT last_name FROM employees WHERE last_name = 'Smith';
如果你只查询被索引的列(即 last_name),并且使用的是 idx_lastname:

Extra: Using index
意味着不需要回表操作,效率更高。

📖 EXPLAIN FORMAT=JSON 示例
EXPLAIN FORMAT=JSON SELECT * FROM employees WHERE department_id = 10;
输出是一个结构化的 JSON 对象,包含详细执行计划,非常适合配合程序分析。例如:

{
"query_block": {
"select_id": 1,
"table": {
"table_name": "employees",
"access_type": "ref",
"key": "dept_idx",
"used_key_parts": ["department_id"],
"rows_examined_per_scan": 100,
"filtered": 100,
"attached_condition": "employees.department_id = 10"
}
}
}
🛠 使用建议
情况 建议
type = ALL 表示全表扫描,考虑加索引
Extra 包含 Using filesort 说明使用了排序算法,考虑优化 ORDER BY
Extra 包含 Using temporary 表示使用了临时表,可能导致性能问题
possible_keys 有值但 key 为 NULL 有可用索引但没被用,可能是查询写法问题或统计信息不准确
🧪 示例练习题(可尝试)
假设你有表结构如下:

CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
customer_id INT,
order_date DATE,
amount DECIMAL(10,2),
INDEX idx_customer (customer_id)
);
试着运行以下 EXPLAIN 语句,观察差异:

EXPLAIN SELECT * FROM orders WHERE customer_id = 123;

EXPLAIN SELECT * FROM orders WHERE amount > 100; -- 没有索引

EXPLAIN SELECT order_date FROM orders WHERE customer_id = 123; -- 覆盖索引

http://www.wxhsa.cn/company.asp?id=654

相关文章:

  • 力扣19题 删除链表的倒数第N个结点
  • 基于LZO的无损数据压缩IP,高性能压缩速率32Gbps,适用于FPGAASIC
  • IDEA创建文件时如何自动生成头部文档注释(简单、实用)
  • 一文带你吃透Power Platform,开启低代码开发新世界
  • docker compose 启动 redis 服务
  • MBR引导的OS Bootloader遇到被bios无视引导(自动重启)的解决办法
  • #java作业
  • 【Qt6】qt6下载地址
  • QOJ1838 Intellectual Implementation 题解
  • OpenSSH漏洞修复
  • 力扣15题三数之和
  • some plan
  • 利用废弃硬件中的零日漏洞:从Netgear路由器到BitDefender盒子的攻击链分析
  • ECT-OS-JiuHuaShan框架:自然规律的具象化智能体(附《易经》类比解析)
  • 力扣第5题最长回文子串
  • 用 Python 和 PaddleOCR 进行验证码识别
  • TASK 1 训练一个网络识别手写数字
  • 复杂背景验证码的识别思路与图像处理方法
  • Symfony学习笔记 - The Symfony Framework Best Practices
  • 大学军训
  • Vue Day3【综合案例2】vue小兔鲜儿
  • Java 基础知识解析
  • 力扣第3题 无重复字符的最长子串
  • UniApp 自定义导航栏
  • P3177 [HAOI2015] 树上染色
  • UniApp 自定义tabBar
  • NOIP2024复盘
  • Avalonia 学习笔记04. Page Navigation(页面导航) (转载)
  • 判断左手坐标系和右手坐标系的方法
  • 题解:P11894 「LAOI-9」Update