MySQL EXPLAIN 查看执行计划详解

MySQL 的 EXPLAIN 命令。这是一个分析和优化 SQL 查询性能不可或缺的强大工具。它展示了 MySQL 如何执行一条 SQL 语句,包括如何使用索引、表连接顺序、估计的行数等关键信息。

1. 如何使用 EXPLAIN

在你要分析的 SELECT 语句前加上 EXPLAIN 或 EXPLAIN FORMAT=JSON(获取更详细的 JSON 格式信息)即可。

EXPLAIN SELECT * FROM users WHERE age > 30;

或者用于分析连接查询:

EXPLAIN SELECT u.name, o.order_id 
FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE u.country = 'China';

2. EXPLAIN 输出列详解

执行 EXPLAIN 后,会返回一个包含多列的结果集。每一列都描述了执行计划的一个特定方面。以下是这些列的详细解释,按重要性排序:

列名描述
id查询中每个 SELECT 子句的唯一标识符。
select_typeSELECT 语句的类型(简单、子查询、联合等)。
table正在访问的表名。
partitions匹配的分区。如果表未分区,则为 NULL
type (非常重要)连接类型 或 访问类型。这是衡量查询效率的关键指标,从最优到最差排列。
possible_keysMySQL 可能选择用来查找该表的索引。
keyMySQL 实际决定使用的索引。如果为 NULL,则未使用索引。
key_len所使用的索引的长度(字节数)。用于判断是否充分利用了索引(例如,复合索引使用了最左前缀的多少部分)。
ref显示索引的哪一列被用来与 key 列指定的索引进行比较,以从表中选择行。
rows (非常重要)MySQL 估计为了找到所需的行而必须检查的行数。这是一个估计值,通常越小越好。
filtered表示存储引擎返回的数据在服务器层过滤后,剩余的行数占估计总行数的百分比。理想是 100%。
Extra (非常重要)包含 MySQL 解决查询的额外信息。这里经常会出现需要重点关注的内容,如是否使用了临时表、文件排序等。

3. 关键列深度解析

1. type (访问类型)

这是最重要的列之一。结果值从好到坏依次是:

  • system: 表只有一行(系统表)。这是 const 类型的特例。

  • const: 通过索引一次就能找到,用于比较 主键 或 唯一索引 的等值查询。速度极快。

EXPLAIN SELECT * FROM users WHERE id = 1; -- id 是主键
  • eq_ref: 在连接查询中,对于来自前表的每一行,从当前表中读取唯一的一行。通常出现在使用 主键 或 唯一索引 的联表查询中。

-- 假设 orders.user_id 是 users.id 的外键,并且有索引
EXPLAIN SELECT * FROM users 
INNER JOIN orders ON users.id = orders.user_id;
  • ref: 使用非唯一性索引进行等值查找,或者使用索引的最左前缀规则进行查找。可能会返回多行。

EXPLAIN SELECT * FROM users WHERE age = 30; -- age 字段有一个普通索引
  • range: 使用索引检索给定范围的行,关键操作符是 BETWEEN><IN 等。

EXPLAIN SELECT * FROM users WHERE age > 20 AND age < 30;
  • index全索引扫描。只遍历索引树来获取数据,通常比 ALL 快,因为索引文件通常比数据文件小。

-- 假设 (age) 是一个索引
EXPLAIN SELECT age FROM users; -- 只需扫描索引,无需回表
  • ALL全表扫描。性能最差,意味着MySQL必须从头到尾扫描整个表来找到匹配的行。如果数据量大,需要优化(如添加索引)。

目标:在查询优化中,我们至少要让 type 达到 range 级别,最好能达到 ref 或以上。

2. Extra (额外信息)

此列包含大量重要信息,常见值及其含义:

  • Using index: 表示查询使用了 覆盖索引(Covering Index),即所有需要的数据都可以从索引中获取,无需回表读取数据行。性能极佳

  • Using where: 表示存储引擎返回行后,MySQL 服务器层还需要再进行过滤(WHERE 子句中的条件不能完全用索引来过滤)。

  • Using temporary: 表示 MySQL 需要创建一个临时表来存储结果以处理查询。常见于 GROUP BY 和 ORDER BY 子句。通常需要优化

  • Using filesort: 表示 MySQL 无法使用索引来完成排序,需要额外的排序操作ORDER BY 、 GROUP BY 可能会引发此问题。在数据量大时性能很差,需要优化

  • Using join buffer (Block Nested Loop): 表示连接查询时,被驱动表没有使用索引,需要用到连接缓冲区。应考虑为被驱动表的连接字段添加索引

  • Impossible WHEREWHERE 子句的条件始终为 false,无法获取任何行。

3. rows

MySQL 根据统计信息估算的需要读取的行数。这个值乘以 filtered 百分比,可以估算出将要和下一张表连接的行数。这个值对于找出性能瓶颈非常有用,值越小越好

4. key

实际使用的索引。如果为 NULL,则说明没有使用索引,需要检查 possible_keys 为什么没有被选用,或者考虑创建合适的索引。


4. 实战分析示例

假设我们有两张表:

users 表

  • id (INT, PRIMARY KEY)

  • name (VARCHAR(100))

  • age (INT)

  • country (VARCHAR(100))

  • 索引: idx_age_country (agecountry)

orders 表

  • order_id (INT, PRIMARY KEY)

  • user_id (INT)

  • amount (DECIMAL)

  • 索引: idx_user_id (user_id)

查询: 查找年龄在 25 到 35 岁之间、来自‘China’的用户的所有订单金额。

EXPLAIN 
SELECT o.amount
FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE u.age BETWEEN 25 AND 35
AND u.country = 'China';

可能的 EXPLAIN 输出分析:

idselect_typetabletypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEurangeidx_age_countryidx_age_country208NULL10010.00Using where
1SIMPLEorefidx_user_ididx_user_id5test.u.id1100.00NULL

逐行解读:

  1. 第一行 (users 表 u):

    • type: range: 很好!使用了索引范围扫描来查找年龄在 25-35 之间的用户。

    • key: idx_age_country: 实际使用了我们创建的复合索引。

    • key_len: 208: 索引使用的长度,可以推断出 age (INT 为 4 字节) 和 country (VARCHAR(100), 假设 utf8mb4 字符集,最坏情况 100*4 + 长度前缀) 部分都被用到了。

    • rows: 100: MySQL 估计大约要扫描 100 行 users 表记录。

    • Extra: Using where: 因为 country='China' 是索引的第二部分,它在索引范围内进行查找(BETWEEN)后,可能还需要用这个条件进一步过滤数据。如果索引是 (country, age),效率可能会更高。

  2. 第二行 (orders 表 o):

    • type: ref: 很好!对于从 u 表找到的每一个 id,通过非唯一索引 idx_user_id 在 o 表中快速查找匹配的行。

    • key: idx_user_id: 实际使用了连接字段上的索引。

    • ref: test.u.id: 使用的是 u.id 的值来查找 o 表。

    • rows: 1: 对于每一个 u.id,MySQL 估计在 o 表中只找到 1 行记录(这是一个很好的估计,假设一个用户只有一个订单)。

结论:这个查询的执行计划相当高效。两张表都有效地使用了索引 (range 和 ref)。没有出现 Using temporary 或 Using filesort 等危险信号。

5. 总结与最佳实践

  1. 关注核心列:优先查看 typekeyrowsExtra 列。

  2. 索引是王道:目标是让 type 达到 range 级别以上,避免出现 ALL(全表扫描)。

  3. 警惕坏信号:在 Extra 列中,出现 Using temporary 和 Using filesort 通常是需要优化的信号,尤其是在大表查询中。

  4. 覆盖索引:努力让 Extra 列出现 Using index,这能极大提升性能。

  5. 联表查询:确保连接条件(ON 子句)和被驱动表(第二张表)的 WHERE 子句上有索引。EXPLAIN 结果中,第一张表是驱动表。

  6. 不要迷信估计rows 列是基于统计信息的估计值,有时可能不准确。可以用 ANALYZE TABLE table_name; 来更新统计信息。

  7. 使用 JSON 格式:对于复杂查询,使用 EXPLAIN FORMAT=JSON 可以获取更详尽的分析信息,包括成本估算。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/97287.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/97287.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TensorFlow 面试题及详细答案 120道(51-60)-- 模型保存、加载与部署

《前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,SQL,Linux… 。 前后端面试题-专栏总目录 文章目录 一、本文面试题目录 51. TensorFlow中保存和加…

从零开始学Shell编程:从基础到实战案例

从零开始学Shell编程&#xff1a;从基础到实战案例 文章目录从零开始学Shell编程&#xff1a;从基础到实战案例一、认识Shell&#xff1a;是什么与为什么学1.1 Shell的定义1.2 常用Shell解释器二、Shell编程快速入门&#xff1a;编写第一个脚本2.1 步骤1&#xff1a;创建脚本文…

机器学习算法全景解析:从理论到实践

机器学习算法全景解析&#xff1a;从理论到实践引言机器学习作为人工智能的核心组成部分&#xff0c;正在深刻地改变我们的世界。从推荐系统到自动驾驶&#xff0c;从医疗诊断到金融风控&#xff0c;机器学习算法无处不在。本文将全面系统地介绍机器学习的主要算法类别及其核心…

week5-[二维数组]对角线

week5-[二维数组]对角线 题目描述 给定一个 nnn\times nnn 的正方形二维数组&#xff0c;输出它两条对角线上元素的和。 输入格式 输入共 n1n 1n1 行。 第 111 行 111 个正整数 nnn。 接下来 nnn 行&#xff0c;每行 nnn 个正整数 aija_{ij}aij​ 表示这个二维数组。 输出格式…

GoogLeNet:深度学习中的“卷积网络变形金刚“

大家好&#xff01;今天我们要聊一个在深度学习领域掀起革命的经典网络——GoogLeNet&#xff08;又称Inception v1&#xff09;。这个由Google团队在2014年提出的模型&#xff0c;不仅拿下了ImageNet竞赛冠军&#xff0c;更用"网络中的网络"设计理念彻底改变了卷积神…

笔记本电脑蓝牙搜索不到设备-已解决

方法1打开疑难解答&#xff0c;选择其他疑难解答&#xff0c;下划选择蓝牙&#xff0c;点击运行&#xff0c;电脑自行检测并修复蓝牙方法2右键此电脑&#xff0c;选择管理&#xff0c;找到自己的蓝牙设备。然后对箭头指向的这个点击右键&#xff0c;选择《更新驱动程序》&#…

WPF 程序用户权限模块利用MarkupExtension实现控制控件显示

工作记录 ------------------------------------------------------------------------------------------------------- MarkupExtension:XAML标记扩展 实现了什么作用&#xff1a;通过扩展标记将一种输入转化为另一种类型的输出 思路&#xff1a; 不直接设置控件的Visib…

SpringMVC相关梳理

SpringMVC 返回值类型&#xff08;一&#xff09;核心返回值类型分类视图渲染类&#xff1a;用于跳转并渲染页面&#xff0c;如String&#xff08;指定视图名&#xff09;、ModelAndView&#xff08;视图 数据&#xff09;。数据返回类&#xff1a;用于返回数据&#xff08;而…

Docker化性能监控平台搭建:JMeter+InfluxDB+Grafana全攻略

你作为一名DevOps工程师或测试专家&#xff0c;正在监控一个高并发微服务系统&#xff1a;突发流量峰值导致响应延迟&#xff0c;服务器CPU飙升&#xff0c;但你只能手动查看日志&#xff0c;优化起来像大海捞针。这时&#xff0c;DockerJMeterInfluxDBGrafana的“梦幻四重奏”…

Adobe Acrobat 中通过 JavaScript 调用 Web 服务

强大的JavaScript支持&#xff0c;允许用户通过脚本自动化处理PDF文档。本文将详细介绍如何在Adobe Acrobat环境中使用JavaScript调用Web服务&#xff0c;包括基础概念、实现方法、代码示例以及常见问题解决方案。 第一部分&#xff1a;基础概念与技术背景 1.1 Acrobat JavaScr…

SpringCloud OpenFeign 远程调用(RPC)(三)

目录 1 概念导入 2 添加依赖 3 在启动类上添加注解 4 编写对应的接口 5 注入并调用 6 日志 7 超时控制 8 超时重试 9 拦截器 10 Fallback兜底 1 概念导入 Spring Cloud OpenFeign Features :: Spring Cloud Openfeign 2 添加依赖 <!-- 远程调用 --><depen…

【Flask】测试平台开发,登陆重构

概述我们在开篇的时候实现了简单的登陆功能&#xff0c;也实现了一个前后端联调的登陆功能&#xff0c;但是你有没有发现&#xff0c;那个登陆只是一个简单的登陆&#xff0c;且密码在接口返回的过程中是铭文密码&#xff0c;在生产环境中使用肯定是不行的&#xff0c;一般密码…

【Bluedroid】A2DP Source设备音频数据读取机制分析(btif_a2dp_source_read_callback)

本文聚焦Android 蓝牙 A2DP Source设备的音频数据读取核心逻辑,深入解析关键回调函数btif_a2dp_source_read_callback的功能实现,包括从 HAL(硬件抽象层,支持 HIDL/AIDL 两种传输方式)或 UIPC(用户空间进程间通信)获取音频数据的路径选择机制,以及数据下溢(Underflow)…

多方调研赋能AI+智慧消防 豪越科技人工智能创新获认可

8月26日&#xff0c;中国职业安全健康协会城市及社区安全发展专业委员会秘书长汪卫国以及常务副秘书长黄强亮等诸位领导到访委员单位豪越科技&#xff0c;展开了实地的调研活动并给予相关指导。此次调研着重于了解豪越科技自主研发的“AI消防救援一体化安全管控平台”&#xff…

算法---字符串

一、算法说明 字符串是一种类型&#xff0c;他不是一种算法&#xff0c;所以我们在处理这方面的问题的时候&#xff0c;需要结合其他的算法 二、题目 最长公共前缀 1、题目 最长公共前缀 2、解题思路 解法一&#xff1a;我们可以先让两个相互比较&#xff0c;然后在将比较…

鸿蒙Next导航与路由指南:组件导航与页面路由的完美协作

一次搞懂HarmonyOS NEXT中的两种导航方式&#xff0c;打造流畅的应用内跳转体验在鸿蒙应用开发中&#xff0c;流畅的页面导航和路由是提升用户体验的关键。HarmonyOS NEXT提供了组件导航&#xff08;Navigation&#xff09; 和页面路由&#xff08;ohos.router&#xff09; 两种…

JavaScript原型详解——面试重点

一、原型的含义&#xff1a;JavaScript 中的“原型”既指 函数身上的 prototype 对象&#xff0c;也指 对象身上的 [[Prototype]] 隐藏链接&#xff1b;它俩共同构成了“原型链”&#xff0c;决定了“找不到属性时去哪里继续找”的规则。&#xff08;1&#xff09;原型对象(pro…

Vue3 全面介绍

Vue3&#xff08;正式名称为 Vue.js 3&#xff09;是 Vue.js 前端框架的第三个主要版本&#xff0c;于 2020 年 9 月正式发布。作为对 Vue2 的重大升级&#xff0c;Vue3 在核心架构、性能优化、开发体验等方面进行了全面重构&#xff0c;同时保持了 Vue 一贯的“渐进式框架”理…

HTTP 范围请求:为什么你的下载可以“断点续传”?

在现代网络应用中&#xff0c;我们习以为常的功能&#xff0c;如断点续传、多线程下载和在线视频快进快退&#xff0c;都依赖于 HTTP 协议中的一个强大特性&#xff1a;范围请求&#xff08;Range Requests&#xff09;。这项技术让客户端能够聪明地只请求文件的一部分&#xf…

万博智云联合华为云共建高度自动化的云容灾基线解决方案

一、摘要 近日&#xff0c;万博智云与华为云的深入合作再添新章——万博智云HyperBDR云容灾解决方案&#xff0c;顺利通过华为云专家团队评审和认证&#xff0c;正式被选为华为云基线解决方案&#xff08;Baseline Solution&#xff09;&#xff0c;并在华为云国际站上线。 Hy…