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优化吗?
近来面试找工作经常会遇见这种问题: 做过数据库优化吗?大数据量基础过吗?系统反应慢怎么查询? 这咱也没背过啊,面试还老问,现在的网站主要的压力都来自于数据库,频繁的数据库访问经常会使系统瘫痪,这样就需 ...
随机推荐
- DeepSpeed: 大模型训练框架
背景: 目前,大模型的发展已经非常火热,关于大模型的训练.微调也是各个公司重点关注方向.但是大模型训练的痛点是模型参数过大,动辄上百亿,如果单靠单个GPU来完成训练基本不可能.所以需要多卡或者分布式训 ...
- .NET Conf 2023 将在 11 月 15日-17 日 举行 ,附中文日程表
北京时间 11月15-17日,.NET Conf 2023 即将到来!大会上将发布.NET 8, 以今为止运行最快的.NET 平台, .NET Conf 始终致力于为所有与会者创造世界级的.引人入胜的 ...
- NewsCenter
打开界面有一个搜索框 抓包查看是post形式提交的数据包 这时候试试sql注入,万能密码直接全都显示,那就说明存在sql注入漏洞 这里试试用sqlmap自动注入试试(POST类型的sql注入第一次尝试 ...
- 如何深度学习Python?
安装必要软件:首先需要安装Anaconda或Miniconda等科研计算环境,并创建虚拟环境以便管理不同项目所需库和版本.可以按照如下步骤进行操作: 下载并安装 Anaconda 或 Minicond ...
- 七天.NET 8操作SQLite入门到实战 - 第二天 在 Windows 上配置 SQLite环境
前言 SQLite的一个重要的特性是零配置的.无需服务器,这意味着不需要复杂的安装或管理.它跟微软的Access差不多,只是一个.db格式的文件.但是与Access不同的是,它不需要安装任何软件,非常 ...
- Silverlight工作流控件功能缺失,Windows Server操作系统 IIS添加WCF功能
注: Silverlight工作流控件,如果在网页中打不开,则要判断是否缺少Silverlight工作流控件的插件程序,如果不是则可以进行一下步骤检查,如果是以下原因则是:由于IIS版本问题,安装后可 ...
- 【scikit-learn基础】--『数据加载』之玩具数据集
机器学习的第一步是准备数据,好的数据能帮助我们加深对机器学习算法的理解. 不管是在学习还是实际工作中,准备数据永远是一个枯燥乏味的步骤.scikit-learn库显然看到了这个痛点,才在它的数据加载子 ...
- 悲观锁、乐观锁、mybatis-plus实现乐观锁
悲观锁.乐观锁.mybatis-plus实现乐观锁 转载自:www.javaman.cn 1.悲观锁.乐观锁 乐观锁和悲观锁是两种用于处理并发操作的数据锁定策略.它们在处理多个事务尝试同时访问和修改同 ...
- c++学习,和友元函数
第一友元函数访问私有元素时不会显示,但是是可以调用的(我使用的是gcc10.3版本的)友元函数可以访问任何元素.就是语法你别写错了. 继承如果父类已经写了构造函数,子类一定要赋值给构造函数,要么父类就 ...
- [ABC261E] Many Operations
Problem Statement We have a variable \(X\) and \(N\) kinds of operations that change the value of \( ...