SQL优化老出错,那是你没弄明白MySQL解释计划用法

目录
  • 1、准备工作
  • 2、初识解释计划
  • 3、字段详解
  • 4、partitions 查询涉及到的分区
  • 5、type 查询的类型
  • 6、possible_keys:预计可能使用的索引
  • 7、key:实际查询的过程中使用的索引
  • 8、key_len
  • 9、ref 显示该表的索引字段关联了哪张表的哪个字段
  • 10、rows:根据表统计信息及选用情况,大致估算出找到所需的记录或所需读取的行数,数值越小越好
  • 11、filtered:返回结果的行数占读取行数的百分比,值越大越好
  • 12、extra
  • 总结

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子句用于限制哪一行

总结

sql 优化的原则就是在保证正确的情况下缩短时间,目标是确定的,通过目标进行回推可以知道想要执行的快就要尽可能的少读数据,减少读取数据的方式大的只有两种过滤和使用索引,在这样的规则范围内进行优化,但是注意索引会占用额外的空间,要平衡好这两者的关系。

到此这篇关于SQL优化老出错,那是你没弄明白MySQL解释计划用法的文章就介绍到这了,更多相关SQL优化 MySQL解释计划内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MySQL执行计划的深入分析

    前言 在之前的面试过程中,问到执行计划,有很多童鞋不知道是什么?甚至将执行计划与执行时间认为是同一个概念.今天我们就一起来了解一下执行计划到底是什么?有什么用途? 执行计划是什么? 执行计划,简单的来说,是SQL在数据库中执行时的表现情况,通常用于SQL性能分析,优化等场景. 一. 执行计划能告诉我们什么? SQL如何使用索引 联接查询的执行顺序 查询扫描的数据函数 二. 执行计划中的内容 SQL执行计划的输出可能为多行,每一行代表对一个数据库对象的操作 1. ID列 ID列中的如果数据为一组数

  • 带你学习MySQL执行计划

    1.执行计划简介 执行计划是指一条 SQL 语句在经过 MySQL 查询优化器的优化会后,具体的执行方式.MySQL 为我们提供了  EXPLAIN 语句,来获取执行计划的相关信息.需要注意的是,EXPLAIN 语句并不会真的去执行相关的语句,而是通过查询优化器对语句进行分析,找出最优的查询方案,并显示对应的信息. 执行计划通常用于 SQL 性能分析.优化等场景.通过 explain 的结果,可以了解到如数据表的查询顺序.数据查询操作的操作类型.哪些索引可以被命中.哪些索引实际会命中.每个数据表

  • mysql执行计划介绍

    烂sql不仅直接影响sql的响应时间,更影响db的性能,导致其它正常的sql响应时间变长.如何写好sql,学会看执行计划至关重要.下面我简单讲讲mysql的执行计划,只列出了一些常见的情况,希望对大家有所帮助. 测试表结构: 复制代码 代码如下: CREATE TABLE `t1` (  `c1` int(11) NOT NULL DEFAULT '0',  `c2` varchar(128) DEFAULT NULL,  `c3` varchar(64) DEFAULT NULL,  `c4`

  • mysql执行计划id为空(UNION关键字)详解

    简介 在工作过程中,有时候会对慢查询进行调优.对于MySQL的SQL语句调优,MySQL本身提供了强大的explain关键字用于查询分析执行计划.本文主要给大家介绍了关于mysql执行计划id为空(UNION关键字)的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的 介绍吧 UNION 操作符用于合并两个或多个 SELECT 语句的结果集.例如,我有两个表,表1记录的是公司男员工的数据,包括年龄.姓名.职位.表2记录的是公司女员工的数据,包括姓名.家庭住址.手机号等字段.这时,

  • SQL优化老出错,那是你没弄明白MySQL解释计划用法

    目录 1.准备工作 2.初识解释计划 3.字段详解 4.partitions 查询涉及到的分区 5.type 查询的类型 6.possible_keys:预计可能使用的索引 7.key:实际查询的过程中使用的索引 8.key_len 9.ref 显示该表的索引字段关联了哪张表的哪个字段 10.rows:根据表统计信息及选用情况,大致估算出找到所需的记录或所需读取的行数,数值越小越好 11.filtered:返回结果的行数占读取行数的百分比,值越大越好 12.extra 总结 1.准备工作 准备三

  • SQL 优化经验总结34条

    (1) 选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE 的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表. (2) WHERE子句中的连接顺序.: ORACLE采用自下而上的顺序解析WHE

  • mysql 查询重复的数据的SQL优化方案

    在mysql中查询不区分大小写重复的数据,往往会用到子查询,并在子查询中使用upper函数来将条件转化为大写.如: 复制代码 代码如下: select * from staticcatalogue WHERE UPPER(Source) IN (SELECT UPPER(Source) FROM staticcatalogue GROUP BY UPPER(Source) having count(UPPER(Source))>1) ORDER BY upper(Source) DESC; 这条

  • SQL优化经验总结

    一. 优化SQL步骤 1. 通过 show status和应用特点了解各种 SQL的执行频率     通过 SHOW STATUS 可以提供服务器状态信息,也可以使用 mysqladmin extende d-status 命令获得. SHOW STATUS 可以根据需要显示 session 级别的统计结果和 global级别的统计结果. 如显示当前session: SHOW STATUS like "Com_%"; 全局级别:show global status;    以下几个参数

  • 分区表场景下的 SQL 优化

    导读 有个表做了分区,每天一个分区. 该表上有个查询,经常只查询表中某一天数据,但每次都几乎要扫描整个分区的所有数据,有什么办法进行优化吗? 待优化场景 有一个大表,每天产生的数据量约100万,所以就采用表分区方案,每天一个分区. 下面是该表的DDL: CREATE TABLE `t1` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `date` date NOT NULL, `kid` int(11) DEFAULT '0', `uid` int(11)

  • MySQL SQL优化教程之in和range查询

    首先我们来说下in()这种方式的查询.在<高性能MySQL>里面提及用in这种方式可以有效的替代一定的range查询,提升查询效率,因为在一条索引里面,range字段后面的部分是不生效的.使用in这种方式其实MySQL优化器是转化成了n*m种组合方式来进行查询,最终将返回值合并,有点类似union但是更高效.同时它存在这一些问题: 老版本的MySQL在IN()组合条件过多的时候会发生很多问题.查询优化可能需要花很多时间,并消耗大量内存.新版本MySQL在组合数超过一定的数量就不进行计划评估了,

  • 记一次SQL优化的实战记录

    目录 前言 1. 创建表 2. 需求 3. 给表插入数据 4. 开始根据需求写SQL 4.1 第一版 4.2 第二版 4.3 第三版 总结 前言 昨天(2022-7-22)上线了我的一个功能,测试环境数据量较小,问题不大,但是上生产之后,直接卡死了,然后就开始了这么一次SQL优化,这里记录一下. 不太方便透露公司的表结构,这里我自己建了几张表,模拟一下就可以了. 肯定有杠精要说表可以不这样设计了,但是事实现在系统就是这样设计的,如果想改动表设计,影响面就太大了(我们急着上线哦).当然,本文的后面

  • 揭秘SQL优化技巧 改善数据库性能

    优化目标 1.减少 IO 次数 IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑,当然,也是收效最明显的优化手段. 2.降低CPU计算 除了 IO 瓶颈之外,SQL优化中需要考虑的就是CPU运算量的优化了.order by, group by,distinct - 都是消耗 CPU 的大户(这些操作基本上都是 CPU 处理内存中的数据比较运算).当我们的 IO 优化做到一定

  • SQL优化之针对count、表的连接顺序、条件顺序、in及exist的优化

    本文详述了SQL优化中针对count.表的连接顺序.条件顺序.in及exist的优化,非常具有实用价值!详述如下: 一.关于count 看过一些网上关于count(*)和count(列)的文章,count(列)的效率一定比count(*)高吗? 其实个人觉得count(*)和count(列)根本就没有可比性,count(*)统计的是表里面的总条数,而count(列)统计的是当列的非空记录条数. 不过我们可以通过实验来比较一下: 首先创建测试表: drop table test purge; cr

  • SQL优化基础 使用索引(一个小例子)

    按照本文操作和体会,会对sql优化有个基本最简单的了解,其他深入还需要更多资料和实践的学习: 1. 建表: 复制代码 代码如下: create table site_user ( id int IDENTITY(1,1) PRIMARY KEY, [name] varchar(20), code varchar(20), date datetime ) 2. 插入8万条数据 复制代码 代码如下: declare @m int set @m=1 while @m<80000 begin INSER

随机推荐