SQL优化老出错,那是你没弄明白MySQL解释计划用法
作者:香菜聊游戏 发布时间:2024-01-27 16:13:43
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子句用于限制哪一行
来源:https://bbs.huaweicloud.com/blogs/306528


猜你喜欢
- 这篇文章主要介绍了Python命令行click参数用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要
- 目录Flyway简介Flyway中的迁移(migrations)模式Flyway历史记录表flyway_history_schemaSpri
- 适配器模式Adapter Pattern是什么适配器模式是一种结构型模式,它可以将一个类的接口转换成客户端所期望的接口,从而使原本不兼容的类
- 目录1、正则表达式1.1 正则表达式字符串1.1.1 元字符1.1.2 字符转义1.1.3 开始与结束字符1.2 字符类1.2.1 定义字符
- 简单低级的爬虫速度快,伪装度低,如果没有反爬机制,它们可以很快的抓取大量数据,甚至因为请求过多,造成服务器不能正常工作。而伪装度高的爬虫爬取
- 数在 Python 中,对数的规定比较简单,基本在小学数学水平即可理解。那么,做为零基础学习这,也就从计算小学数学题目开始吧。因为从这里开始
- 一、re.compile 函数作用:compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match()
- 抢票脚本,python +splinter自动刷新抢票,可以成功抢到(依赖自己的网络环境太厉害,还有机器的好坏),但是感觉不是很完美。有大神
- 导航是网页设计的重点,我们在设计一个网站的时候,常常从导航入手,不夸张的说,导航的设计甚至决定了整个网站的风格。这就需要我们平常多留心收集优
- 前言功能新增学生显示学生查找学生删除学生存到文档创建入口函数在入口函数中,可以先打印一个菜单,用菜单来进行交互。def menu(): &n
- 创建变量变量是存放数据值的容器。与其他编程语言不同,Python 没有声明变量的命令。首次为其赋值时,才会创建变量。实例x = 10y =
- 最初的声明方式在没有@property修饰的情况下,需要分别声明get、set、delete函数,然后初始化property类,将这些方法加
- 很对编程语言都支持递归函数,Go语言也不例外,所谓递归函数指的是在函数内部调用函数自身的函数,从数学解题思路来说,递归就是把一个大问题拆分成
- 项目需求:浏览器中访问django后端某一条url(如:127.0.0.1:8080/get_book/),实时朝数据库中生成一千条数据并将
- display_errors 错误回显,一般常用语开发模式,但是很多应用在正式环境中也忘记了关闭此选项。错误回显可以暴露出非常多的敏感信息,
- 本文实例讲述了JS实现带鼠标效果的头像及文章列表代码。分享给大家供大家参考。具体如下:这是一种带图片功能的文章或新闻列表功能,鼠标滑过标题列
- 1. 简述我们在用scrapy爬取数据时,首先就要明确我们要爬取什么数据。scrapy提供了Item对象这种简单的容器,我们可以通过Item
- click() 对象.click() 使对象被点击。 closed 对象.closed 对象窗口是否已关闭true/false clearT
- 这些标记告诉预处理器,它们包含代码,并且应对它们作出处理。与 CGI 非常相似,这些代码在服务器上运行,并返回一些内容,这些内容表现为发回给
- 之前上传图片都是直接将图片转化为io流传给服务器,没有用框架传图片。最近做项目,打算换个方法上传图片。Android发展到现在,Okhttp