SQL优化老出错,那是你没弄明白MySQL解释计划
摘要:数据库的解释计划阐明了sql的执行过程,展示了执行的细节,只要根据数据库告诉我们的问题按图索骥的分析就可以。
本文分享自华为云社区《轻松搞懂mysql的执行计划,再也不怕sql优化了》,作者:香菜聊游戏。
近期要做一些sql优化的工作,虽然记得一些常用的sql 优化技巧,但是在工作中还是不够,所以需要借助工具的帮助,数据库的解释计划阐明了sql的执行过程,展示了执行的细节,我们只要根据数据库告诉我们的问题按图索骥的分析就好了,但是解释计划也不是那么容易看懂,所以今天就学习下解释计划的一些参数的意义。
1、准备工作
准备三张表,一张角色表,一张装备表,一张基础数据表,这里只展示一些教程中需要的字段,在游戏开发的过程中肯定不止这么几个字段,我想大家都懂的。
角色表:
CREATE TABLE `role` (
`n_role_id` int DEFAULT NULL,
`s_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
装备表:
CREATE TABLE `equip` (
`n_equip_id` int DEFAULT NULL,
`s_equip_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`n_config_id` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
装备配置表
CREATE TABLE `dict_equip` (
`n_equip_id` int DEFAULT NULL,
`s_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
2、初识解释计划
有两种方式可以查看解释计划:
1、命令的方式:explain sql,或者 desc sql ,两个命令都可以,我觉得记住explain比较好,单词很直接。
2、借助工具 Navicat(其他的不熟,估计也有),点击查询窗口的解释,可以不用加关键字explain

可以看到结果里面包含了很多列,有的是null 有的有值,只要我们看懂了解释计划是不是就可以有的放矢的优化sql。
3、字段详解
解释计划的字段还是蛮多的,Navicat显示了12个字段,有些字段我们需要重点关注,有些知道怎么回事就好了。
官方的文档解释:https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
1、id 执行的顺序
id 是select的执行顺序,id越大优先级越高,越先被执行,id 相同时 下面的先执行.
原因是因为执行子查询时,先查内层的,再查外层
SELECT
de.*
FROM
dict_equip de
WHERE
de.n_equip_id = (
SELECT n_equip_id FROM equip e WHERE
e.n_role_id = (
SELECT n_role_id FROM role r WHERE r.s_name = '香菜' )
)

从上面的执行计划可以看到先执行了查询role表,后执行了equip ,最后执行了 dict_equip
2、select_type select 的类型

3、table 查询涉及的表或衍生表
当前输出的正在使用的表,可以有下面几种:
<unionM,N> : 行数据是联合之后的数据id 处于 m和 n
<derived*N*>: 衍生表
<subqueryN>: 子查询
4、partitions 查询涉及到的分区
在使用分区表的时候才能用到,暂时没用到过这种高级功能。
5、type 查询的类型
表示MySQL在表中找到所需行的方式,又称“访问类型”,常见类型如下:

性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
由左至右,由最差到最好
在进行优化的时候如果查询出的数据量大的话可以使用全表扫描,避免使用索引。
如果只是查询很少的数据尽量使用索引。
6、possible_keys:预计可能使用的索引
在不和其他表进行关联的时候,查询表的是可能使用的索引
7、key:实际查询的过程中使用的索引
显示MySQL在查询中实际使用的索引,若没有使用索引,显示为NULL
8、key_len
表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度
9、ref 显示该表的索引字段关联了哪张表的哪个字段

注: 我在equip 和 dict_equip 两张表都分别添加了索引,索引列是n_equip_id
通过上面的执行计划可以看出,首先使用了索引
10、rows:根据表统计信息及选用情况,大致估算出找到所需的记录或所需读取的行数,数值越小越好
比如 一个列上 虽然没做索引,但是都是唯一的,这个时候查找的时候如果是全表读取,就是表里有多少数据这个值就是多少,这个时候你需要优化的就是尽可能的读取少的表,可以增加索引,减少读取行数
11、filtered:返回结果的行数占读取行数的百分比,值越大越好
比如全表有100条数据,可能读取了全表数据,但是只有一条匹配上,这个时候百分比就是1,所以你需要让这个比例越大越好,也就是读到的数据尽量都是有用的,避免读取不用的数据,因为IO是很费时的。
12、extra
常见的有下面几种
use filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行,如果是这个值,应该优化索引。
use temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果。典型情况如查询包含可以按不同情况列出列的GROUP BY和ORDER BY子句时。
use index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。当查询只使用作为单一索引一部分的列时,可以使用该策略
use where:where子句用于限制哪一行
4、总结
sql 优化的原则就是在保证正确的情况下缩短时间,目标是确定的,通过目标进行回推可以知道想要执行的快就要尽可能的少读数据,减少读取数据的方式大的只有两种过滤和使用索引,在这样的规则范围内进行优化,但是注意索引会占用额外的空间,要平衡好这两者的关系。
SQL优化老出错,那是你没弄明白MySQL解释计划的更多相关文章
- 浅谈SQL优化入门:2、等值连接和EXPLAIN(MySQL)
1.等值连接:显性连接和隐性连接 在<MySQL必知必会>中对于等值连接有提到两种方式,第一种是直接在WHERE子句中规定如何关联即可,那么第二种则是使用INNER JOIN关键字.如下例 ...
- log日志重复输出问题(没弄明白原因)
在别的模块调用定义好的函数 输出的日志出现第一次输出输出一条,第二次输出输出两条...的情况 最后在定义函数处remove了句柄 引用了https://blog.csdn.net/huilan_sam ...
- Context都没弄明白,还怎么做Android开发?
Activity mActivity =new Activity() 作为Android开发者,不知道你有没有思考过这个问题,Activity可以new吗?Android的应用程序开发采用JAVA语言 ...
- Context都没弄明白,还怎么做Android开发
转载:https://www.jianshu.com/p/94e0f9ab3f1d Activity mActivity =new Activity() 作为Android开发者,不知道你有没有思考过 ...
- php中那些我还没弄明白的名词解释
1.正则表达式引擎,引擎是什么? 2.语言构造器和函数的区别 3.可变函数
- MySQL5.6 怎样优化慢查询的SQL语句 -- SQL优化
上篇:MySQL5.6 怎样优化慢查询的SQL语句 -- 慢日志介绍 在实际的日志分析中,通常慢日志的log数量不少,同一时候同样的查询被记录的条数也会非常多.这里就须要怎样从慢日志查询中找到最有问题 ...
- SQL优化常用的几种方法
为什么要对SQL优化: 1.执行性能低 2.等待时间过长 3.SQL写的太差 4.索引失效 ·····等等 SQL优化的一些方法: 1.EXPLAIN 做MySQL优化,我们要善用EXPLAIN查看S ...
- 没内鬼,来点干货!SQL优化和诊断
SQL优化与诊断 Explain诊断 Explain各参数的含义如下: 列名 说明 id 执行编号,标识select所属的行.如果在语句中没有子查询或关联查询,只有唯一的select,每行都将显示1. ...
- 关于数据库SQL优化
1.数据库访问优化 要正确的优化SQL,我们需要快速定位能性的瓶颈点,也就是说快速找到我们SQL主要的开销在哪里?而大多数情况性能最慢的设备会是瓶颈点,如下载时网络速度可能会是瓶颈点,本地复制文件 ...
- 面试:做过sql优化吗?
近来面试找工作经常会遇见这种问题: 做过数据库优化吗?大数据量基础过吗?系统反应慢怎么查询? 这咱也没背过啊,面试还老问,现在的网站主要的压力都来自于数据库,频繁的数据库访问经常会使系统瘫痪,这样就需 ...
随机推荐
- angular,vue,react三大框架选型
三大框架,本质都是基于js的web应用(前端做的都是web应用包括移动)框架,他们都是帮助我们解决问题的工具,具体用哪个,要结合具体场景. 这三者中,Angular的适用领域相对窄一些,React可以 ...
- arm架构docker安装nacos
前言 搞了个hk1box,装了armbian系统,想用这个当服务器调试微服务,需要安装nacos.尝试安装非docker版本的nacos,去github下载arm版本的并且放到linux下面,运行的时 ...
- openwrt使用tailscale实现内网穿透
问题 之前一直有电信公网ip,最近发现电信公网ip被撤下来了,打电话再去要发现给的是10开头的ip,电信客服还跟我说10开头就是公网ip,= =,根本就不是,无奈使用zerotier进行打洞,把zer ...
- 机器学习从入门到放弃:硬train一发手写数字识别
一.前言 前面我们了解了关于机器学习使用到的数学基础和内部原理,这一次就来动手使用 pytorch 来实现一个简单的神经网络工程,用来识别手写数字的项目.自己动手后会发现,框架里已经帮你实现了大部分的 ...
- 一文概览NLP句法分析:从理论到PyTorch实战解读
关注TechLead,分享AI全维度知识.作者拥有10+年互联网服务架构.AI产品研发经验.团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士,上亿营收AI ...
- Util应用框架基础(六) - 日志记录(一) - 正文
本文介绍Util应用框架如何记录日志. 日志记录共分4篇,本文是正文,后续还有3篇分别介绍写入不同日志接收器的安装和配置方法. 概述 日志记录对于了解系统执行情况非常重要. Asp.Net Core ...
- TIOBE 11月榜单:Java和 C# 之间的差距缩小到0.7
TIOBE 公布了 2023 年 11 月的编程语言排行榜. 虽然这期重点介绍的是Kotlin,本月,它的排名上升了 0.17%,从第 18 位上升到第 15 位,前进了 3 位. TIOBE的10月 ...
- L3-013 非常弹的球
初速度:\(v = \sqrt{\cfrac{2 * E}{m}};\) 竖直速度:\(v_y = v \,sin(ans) = g * t\) 水平距离:\(s = v_x * 2t = v \, ...
- python列表删除元素之del,pop()和remove()
del函数 如果知道要删除元素在列表中的位置,可以使用del语句: list_1 = ['one', 'two', 'three'] print(list_1) del list_1[0] print ...
- 在路上---学习篇(一)Python 数据结构和算法 (1)
数据结构和算法 现阶段的肤浅理解数据结构是各式各样的类型数据在内存中是如何构造的,原理是怎么样的. 了解了其本质后,在面对问题时候,根据数据结构利用算法计算可以最快,最有效的完成任务.通常情况下,精心 ...