做一个积极的人

编码、改bug、提升自己

我有一个乐园,面向编程,春暖花开!

昨天分享了Mysql中的 explain 命令,使用 explain 来分析 select 语句的运行效果,如 :explain可以获得select语句使用的索引情况、排序的情况等等。链接:顺便提到了explain extended,有小伙伴留言说想知道一些explain extended,那今天就在简单讲解一下。

一、explain extended说明

我昨天的文章使用explain extended是在mysql5.6版本执行的,所以用explain extended查看执行计划会比explain多一列 filtered。如果你是用的mysql5.7的话,那默认explain 就会输出 filtered 这一列,不需要使用explain extended了。

-- 查询mysql版本
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.24 |
+-----------+
1 row in set

MySQL 5.7 Reference Manual

在对每一个列进行一个简单说明:

Column Meaning
id SELECT标识符
select_type SELECT类型
table SELECT类型
partitions 匹配的分区
type 连接类型
possible_keys 可供选择的索引
key 实际选择的索引
key_len 所选key的长度
ref 列与索引进行比较
rows 估计要检查的行
filtered 按表条件过滤的行的百分比
Extra 附加/额外信息

filtered 这一列的解释

  • 筛选列指示将按表条件筛选的表行的估计百分比。 最大值为100,这意味着不会对行进行过滤。 值从100开始减少表示过滤量增加。 rows显示检查的估计行数,rows×filtered显示将与下表连接的行数。 例如,如果rows 是1000且filtered为50.00(50%),则使用下表连接的行数为1000×50%= 500。

二、调优案例,一定要看哦!

四张表,分别为:

  • camera :相机

  • unit :区域

  • task

  • task_relation

四张表的数据信息如下(刚开始没有加额外索引), 只有camera的数据量相对较大,其他一般!

-- camera 表信息
mysql> select count(*) from camera;
+----------+
| count(*) |
+----------+
| 52668 |
+----------+ -- unit 表信息
mysql> select count(*) from unit;
+----------+
| count(*) |
+----------+
| 227 |
+----------+ -- task 表信息
mysql> select count(*) from task;
+----------+
| count(*) |
+----------+
| 771 |
+----------+ -- task_relation 表信息
mysql> select count(*) from task_relation;
+----------+
| count(*) |
+----------+
| 44 |
+----------+ --- 查询索引,Key_name都是主键,如unit 、task、task_relation
mysql> show indexes from camera;
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| camera | 0 | PRIMARY | 1 | id | A | 51744 | NULL | NULL | | BTREE | | |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set

1、没有加任何索引情况

有一个查询的sql,看一下如何进行在没有任何额外索引的情况下,执行耗时是多少?(请忽略这条sql具体是什么含义)

SELECT
temp.id,
temp.brandname,
temp.ip,
temp.address,
temp. NAME,
temp.url,
temp.serialnumber,
temp.thumbNail,
temp.region,
temp.create_time,
temp.taskId,
vt.isvalid
FROM
(
SELECT
c.id AS id,
c.brandname AS brandname,
c.ip AS ip,
c.address AS address,
c.`name` AS NAME,
c.url AS url,
r.serialnumber AS serialnumber,
c.thumb_nail AS thumbNail,
t.unit_name AS region,
c.create_time,
r.serialnumber AS taskId
FROM
camera c
LEFT JOIN task_relation r ON c.id = r.camera_file_id
LEFT JOIN unit t ON t.unit_identity = c.region
) temp
LEFT JOIN task vt ON temp.serialnumber = vt.serialnumber
WHERE
1 = 1
ORDER BY
temp.create_time DESC,
temp. NAME DESC

执行耗时结果为: 10s 左右!

使用explain分析如下:

+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+----------------------------------------------------+
| 1 | SIMPLE | c | NULL | ALL | NULL | NULL | NULL | NULL | 52116 | 100 | Using temporary; Using filesort |
| 1 | SIMPLE | r | NULL | ALL | NULL | NULL | NULL | NULL | 44 | 100 | Using where; Using join buffer (Block Nested Loop) |
| 1 | SIMPLE | t | NULL | ALL | NULL | NULL | NULL | NULL | 227 | 100 | Using where; Using join buffer (Block Nested Loop) |
| 1 | SIMPLE | vt | NULL | ALL | NULL | NULL | NULL | NULL | 729 | 100 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+----------------------------------------------------+
4 rows in set

发现联接类型type为ALL,根据上一篇的介绍:

ALL:对于每个来自于先前的表的行组合,进行完整的表扫描。

2、给关联查询的字段加上索引

使用第一篇 添加索引的方法,分别为查询语句中on关联的字段加上索引,如下:

-- 创建普通索引命令之一
ALTER TABLE table_name ADD INDEX index_name(col_name);
-- 创建相应的索引 mysql> ALTER TABLE task_relation ADD INDEX index_camera_file_id(camera_file_id);
Query OK, 0 rows affected
mysql> ALTER TABLE unit ADD INDEX index_unit_identity(unit_identity);
Query OK, 0 rows affected

创建到两个索引的时候,使用Explain看一下,发现type就有ref了,possible_keys 和key都有索引了。

+----+-------------+-------+------------+------+----------------------+----------------------+---------+---------------+-------+----------+----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+----------------------+----------------------+---------+---------------+-------+----------+----------------------------------------------------+
| 1 | SIMPLE | c | NULL | ALL | NULL | NULL | NULL | NULL | 52116 | 100 | Using temporary; Using filesort |
| 1 | SIMPLE | r | NULL | ref | index_camera_file_id | index_camera_file_id | 8 | test.c.id | 1 | 100 | NULL |
| 1 | SIMPLE | t | NULL | ref | index_unit_identity | index_unit_identity | 99 | test.c.region | 1 | 100 | NULL |
| 1 | SIMPLE | vt | NULL | ALL | NULL | NULL | NULL | NULL | 729 | 100 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------------+------+----------------------+----------------------+---------+---------------+-------+----------+----------------------------------------------------+
4 rows in set

验证一下添加索引的效果,此时进行一次查询,耗时为 6S左右!

给剩下没有加索引的表在继续加上索引:

[SQL]ALTER TABLE camera ADD INDEX index_region(region);
受影响的行: 0
时间: 2.277s
[SQL]ALTER TABLE task ADD INDEX index_serialnumber(serialnumber);
受影响的行: 0
时间: 0.435s

:给camera加索引花费的时间较大。如果前期知道是大表的话,一定要设计索引,否则当数据量特别大的时候,加索引就麻烦了。

3、索引全部创建完后

在创建所有查询关联的字段索引后,在执行explian进行分析,如下:

+----+-------------+-------+------------+------+----------------------+----------------------+---------+---------------------+-------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+----------------------+----------------------+---------+---------------------+-------+----------+----------------+
| 1 | SIMPLE | c | NULL | ALL | NULL | NULL | NULL | NULL | 52116 | 100 | Using filesort |
| 1 | SIMPLE | r | NULL | ref | index_camera_file_id | index_camera_file_id | 8 | test.c.id | 1 | 100 | NULL |
| 1 | SIMPLE | t | NULL | ref | index_unit_identity | index_unit_identity | 99 | test.c.region | 1 | 100 | NULL |
| 1 | SIMPLE | vt | NULL | ref | index_serialnumber | index_serialnumber | 194 | test.r.serialnumber | 1 | 100 | NULL |
+----+-------------+-------+------------+------+----------------------+----------------------+---------+---------------------+-------+----------+----------------+
4 rows in set

执行sql,查询耗时 0.5 s 左右!

三、总结

通过上面的简单的案例,将一个开始执行10s左右的sql修改为最后执行0.5s左右! 快了20倍!

索引的添加以及SQL调优还有很多的东西,我要走的路还很远!但是我觉得首先是掌握必要的一些知识,然后能进行简单的应用,慢慢一步一步向前。

本篇的分析就到这里,希望看完本篇内容内容的你也可以动手实际操作一下,我将本篇对应的初始化数据库脚本传到github上面了,地址:https://github.com/dufyun/learn-tech-collection/tree/master/mysql_tuning,你可以进行下载实践。

最后,想分享的是 思路有时候比答案(结果)更重要。


谢谢你的阅读,如果您觉得这篇博文对你有帮助,请点赞或者喜欢,让更多的人看到!祝你每天开心愉快!


不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!

博客首页 : http://blog.csdn.net/u010648555

愿你我在人生的路上能都变成最好的自己,能够成为一个独挡一面的人

© 每天都在变得更好的阿飞云

必读,sql加索引调优案例和explain extended说明的更多相关文章

  1. SQL Server ->> 性能调优案例之 -- 包含递归查询的视图导致整个查询语句性能下降

    有个语句最近性能下降很厉害,原本1秒就可以查询完毕的事情现在居然需要3-4分钟. 首先我的做法是先快速找出导致整个语句下降的元凶.在这个例子里面查询语句有3个JOIN字句,我通过删除某一个JOIN节点 ...

  2. SQL Server索引调优系列

    http://www.cnblogs.com/chenmh/category/586612.html http://www.cnblogs.com/zhijianliutang/category/63 ...

  3. OCM_第十四天课程:Section6 —》数据库性能调优_各类索引 /调优工具使用/SQL 优化建议

    注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...

  4. sql server 性能调优之 资源等待PAGELATCH

    一.概述 在前几章介绍过 sql server 性能调优资源等待之PAGEIOLATCH,PAGEIOLATCH是出现在sql server要和磁盘作交互的时候,所以加个IO两个字.这次来介绍PAGE ...

  5. SQL Server性能调优系列

    这是关于SQL Server调优系列文章,以下内容基本涵盖我们日常中所写的查询运算的分解以及调优内容项,皆为原创........ 第一个基础模块注重基础内容的掌握,共分7篇文章完成,内容涵盖一系列基础 ...

  6. SQL Server 性能调优培训引言

    原文:SQL Server 性能调优培训引言 大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤 ...

  7. mysql数据库索引调优

    一.mysql索引 1.磁盘文件结构 innodb引擎:frm格式文件存储表结构,ibd格式文件存储索引和数据. MyISAM引擎:frm格式文件存储表结构,MYI格式文件存储索引,MYD格式文件存储 ...

  8. sql server 性能调优之 资源等待 LCk

    一.  概述 这次介绍实例级别资源等待LCK类型锁的等待时间,关于LCK锁的介绍可参考 “sql server 锁与事务拨云见日”.下面还是使用sys.dm_os_wait_stats 来查看,并找出 ...

  9. sql server 性能调优之 CPU消耗最大资源分析1 (自sqlserver服务启动以后)

    一. 概述 上次在介绍性能调优中讲到了I/O的开销查看及维护,这次介绍CPU的开销及维护, 在调优方面是可以从多个维度去发现问题如I/O,CPU,  内存,锁等,不管从哪个维度去解决,都能达到调优的效 ...

随机推荐

  1. PowerDesigner 打印错误

    PowerDesigner打开pdm文件时报“打印错误”(解决)   原创作品,出自 “深蓝的blog” 博客,欢迎转载,转载时请务必注明出处,否则追究版权法律责任. 深蓝的blog:http://b ...

  2. python+正态分布+蒙特卡洛预测男女身高概率!

    sklearn实战-乳腺癌细胞数据挖掘 https://study.163.com/course/introduction.htm?courseId=1005269003&utm_campai ...

  3. linux系统root密码忘了怎么办 三种方法快速找回root密码

    linux root密码找回方法一 第1步:在系统进入单用户状态,直接用passwd root去更改. 第2步:用安装光盘引导系统,进行linux rescue状态,将原来/分区挂接上来,作法如下: ...

  4. 数学:二次剩余与n次剩余

    二次剩余求的是这个东西 如果给定x,再给定若干个大的质数p,如果结果a相同,那么x是完全平方数? 给出别人的二次剩余的代码: /*poj 1808 题意: 判断平方剩余,即判断(x^2)%p=a是否有 ...

  5. OpenResty 扩展库(二)lua-resty-template

    Lua和OpenResty的模板引擎(HTML) 模板语法 您可以在模板中使用以下标签: {{expression}},写入表达式的结果 - html转义 {*expression*},写入表达结果 ...

  6. [转载]Frontend Knowledge Structure

    https://github.com/JacksonTian/fks http://code.csdn.net/news/2819224 本文为大家整理了一系列关于JavaScript的常用工具,包括 ...

  7. 2016-2017-2 20155309 南皓芯java第六周学习总结

    教材内容详解 这一次主要学习的是第十章与第十一章的内容.主要讲述了串流,字符处理和线程以及并行API. 输入输出 串流:Java中的数据有来源(source)和目的地(destination),衔接两 ...

  8. v140平台工具集与v110工具集选择

    今天在编译用vs2012编译C++动态库提示:error MSB8020: The builds tools for v140_xp (Platform Toolset = 'v140_xp') ca ...

  9. Javascript - 预编译与函数词法作用域

    预编译与函数词法作用域(Precompiled & Scoped) 预编译 Javascript脚本的宿主在执行代码之前对脚本做了预编译处理,比如浏览器对Js进行了预编译,编译器会扫描所有的声 ...

  10. 关于USBHID协议以及鼠标键盘描述符的解释【转】

    转自:https://blog.csdn.net/jiujiujiuqiuqiuqiu/article/details/47277685 一.HID设备识别 前面有提到关于SCSI协议的USB设备实现 ...