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

SQL 调优第一步:EXPLAIN 关键字全解析

目录

一、Explain核心概念

二、实战 

2.1 简述功能

🔍什么是查询块?

 2.2 详细解析

2.2.1 id--查询块的唯一序号

2.2.2 select_type--该查询块的类型

2.2.3  table--本次访问的表(或别名)

2.2.4 type--访问方式(性能等级)

2.2.5 possible_keys--可供选择的索引列表

2.2.6 key--实际使用的索引

2.2.7 key_len--所用索引的字节长度

2.2.8 ref--与索引列等值匹配的列或常量

2.2.9 rows--预估需扫描的行数

2.2.10 Extra--额外执行信息


一、Explain核心概念

使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,而不是直接运行,开发者就可以通过对模拟的分析再决定是加索引、改写 SQL,还是调整表结构。

🧠根据对explain结果的分析,可以得到以下结果:

  1. 全表的读取顺序id + table:决定多表 JOIN 时先读哪张表、后读哪张表。

  2. 数据读取操作的操作类型type:system / const / ref / range / ALL 等。

  3. 哪些索引可以使用possible_keys:优化器候选索引列表。

  4. 哪些索引被实际使用key:真正被采用的索引。

  5. 表之间的引用ref:显示当前表用到了哪张表的哪一列做等值匹配。

  6. 每张表有多少行被优化器查询rows:估计要扫描的行数。 

二、实战 

2.1 简述功能

字段代表含义
id查询块的唯一序号
select_type该查询块的类型
table本次访问的表(或别名)
type访问方式(性能等级)
possible_keys可供选择的索引列表
key实际使用的索引
key_len所用索引的字节长度
ref与索引列等值匹配的列或常量
rows预估需扫描的行数
Extra额外执行信息

🔍什么是查询块?

 查询块 = 语句树中每个独立 SELECT 的小节点。EXPLAIN 的 id 就是给这些节点按出现的先后顺序编号。

场景示例包含几个查询块
SELECT * FROM t_student;1
SELECT * FROM t_student WHERE id IN (SELECT id FROM t_score);2(外层 1,子查询 1)
SELECT * FROM t1 UNION SELECT * FROM t2;2(每个 UNION 分支 1)
SELECT * FROM (SELECT * FROM t_student) AS s;2(派生表 1,外层 1)

 2.2 详细解析

可以看出调用这个SQL语句后,得到了下面的行元素值,下面逐一分析:

2.2.1 id--查询块的唯一序号

💡详细说明

  • 每个 SELECT 语句都会被分配一个唯一的 id

  • 数字越大,执行顺序越靠前

  • id 相同表示这些查询块是同一级别的,执行顺序由上至下

  • id 为 NULL 表示这是一个结果集,不需要使用它来进行查询

2.2.2 select_type--该查询块的类型

💡详细说明

  • SIMPLE:简单查询(不包含子查询或 UNION)

  • PRIMARY:最外层的查询

  • SUBQUERY:子查询中的第一个 SELECT

  • DERIVED:派生表(FROM 子句中的子查询)

  • UNION:UNION 中第二个及以后的 SELECT

  • UNION RESULT:UNION 的结果

  • DEPENDENT SUBQUERY:依赖于外部查询的子查询

  • UNCACHEABLE SUBQUERY:结果不能被缓存的子查询

2.2.3  table--本次访问的表(或别名)

💡详细说明

  • 显示表名或表的别名
  • 如果是派生表,会显示为 <derivedN>,其中 N 是 id 值

  • 如果是 UNION 结果,会显示为 <unionM,N,...>

2.2.4 type--访问方式(性能等级)

💡详细说明(从最优到最差排序):

  • system:表只有一行记录(系统表)

  • const:通过主键或唯一索引一次就找到

  • eq_ref:关联查询中,使用主键或唯一索引关联

  • ref:使用非唯一索引扫描或唯一索引前缀扫描

  • fulltext:使用全文索引

  • ref_or_null:类似 ref,但包含 NULL 值的查询

  • index_merge:使用了索引合并优化

  • unique_subquery:IN 子查询中使用唯一索引

  • index_subquery:IN 子查询中使用非唯一索引

  • range:索引范围扫描

  • index:全索引扫描

  • ALL:全表扫描(最差情况)

2.2.5 possible_keys--可供选择的索引列表

💡详细说明

  • 显示可能应用在这张表中的索引

  • 如果为 NULL,则表示没有可用的索引

  • 实际查询时可能不会使用这些索引

2.2.6 key--实际使用的索引

💡详细说明

  • 显示 MySQL 实际决定使用的索引

  • 如果为 NULL,则表示没有使用索引

  • 可能出现在 possible_keys 中,也可能不出现(MySQL 优化器自行判断)

2.2.7 key_len--所用索引的字节长度

💡详细说明

  • 表示索引中使用的字节数

  • 可计算查询中使用的索引长度(越短越好)

  • 对于复合索引,可以判断使用了哪些部分

2.2.8 ref--与索引列等值匹配的列或常量

💡详细说明

  • 显示索引的哪一列被使用了

  • 可能是一个常量(const)、列名或函数

  • 如果为 NULL,表示没有引用

2.2.9 rows--预估需扫描的行数

💡详细说明

  • MySQL 估计为了找到所需的行而要读取的行数

  • 是一个预估值,不是精确值

  • 对于 InnoDB 表,这个数字是估计值

2.2.10 Extra--额外执行信息

💡常见值及说明

  • Using index:使用了覆盖索引(只需索引就能获取数据)

  • Using where:在存储引擎检索后再过滤

  • Using temporary:需要使用临时表

  • Using filesort:需要额外排序操作

  • Using join buffer:使用了连接缓存

  • Impossible WHERE:WHERE 子句始终为 false

  • Select tables optimized away:通过索引优化,可能不需要访问表

http://www.dtcms.com/a/288640.html

相关文章:

  • 【已解决】GitHub SSH 连接失败解决方案:Permission Denied (publickey) 错误修复指南
  • [Linux]进程 / PID
  • 30天打牢数模基础-决策树讲解
  • Linux入门篇学习——NFS 服务器的搭建和使用和开发板固件烧录
  • Spring Boot 第一天知识汇总
  • 【Java项目安全基石】登录认证实战:Session/Token/JWT用户校验机制深度解析
  • 相似度计算
  • 「Java案例」利用方法求反素数
  • Facebook 开源多季节性时间序列数据预测工具:Prophet 饱和预测 Saturating Forecasts
  • dynamic_cast的实现原理
  • Beamer-LaTeX学习(教程批注版)【6】
  • Elasticsearch 简化指南:GCP Google Compute Engine
  • GPT-4o mini TTS:领先的文本转语音技术
  • 随着GPT-5测试中泄露OpenAI 预计将很快发布 揭秘GPT-5冲击波:OpenAI如何颠覆AI战场,碾压谷歌和Claude?
  • prometheus 黑盒监控和docker检测
  • mysql第三次作业
  • 学习寄存器——GPIO(二)学习BSRR BRR ODR寄存器的原子性和在HAL库的应用
  • 【Go语言-Day 22】解耦与多态的基石:深入理解 Go 接口 (Interface) 的核心概念
  • 【详细笔记】两类曲线积分转换
  • 群组功能实现指南:从数据库设计到前后端交互,上班第二周
  • 【数据结构】揭秘二叉树与堆--用C语言实现堆
  • 人工智能之数学基础:随机实验、样本空间、随机事件
  • Docker Desktop 入门教程(Windows macOS)
  • 深度学习图像分类数据集—百种病虫害分类
  • Python绘图小工具开发:从零构建数据可视化利器
  • 股票及金融笔记
  • 如何升级Docker部署的Dify
  • Materials Studio学习笔记(二十九)——尿素的几何优化
  • 私有云新势力:Puter+CPolar如何低成本替代商业网盘?
  • 【Linux性能优化】常用工具和实战指令