IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> Mysql高级调优篇——第二章:Explain执行计划深度剖析 -> 正文阅读

[大数据]Mysql高级调优篇——第二章:Explain执行计划深度剖析

1、Mysql Query Optimizer

? ? ? ? 这个名称在前言部分我在Mysql的整体架构中介绍过,称为查询优化器;这个查询优化器在绝大多数的公司,是不会做任何修改和扩展的,因为业务不需要,大牛请不起等因素,也就除了阿里这些大厂变态到把这玩意改了自己用。

? ? ? ? Mysql中有专门负责优化Select语句的优化器模块,主要功能是:通过计算分析系统中手记到的统计信息,为客户端请求的Query提供Mysql认为最优化的执行计划,认为最优的检索方式,但是不一定是DBA认为是最优的,所以这部分是调整起来最耗时间的。

? ? ? ? 当客户端向Mysql请求一条查询的时候,命令解析器会完成请求的分类,区别出是Select操作,并转发给Mysql Query Optimizer时,Optimizer首先会对整个Query进行优化,处理掉一些常量表达式的运算,直接换算成常量值,或者根据查询条件出现的顺序进行个位置交换,如去掉一些无用或者显而易见的条件,结构调整等。然后分析Query的Hint信息(如果存在的话),看显示Hint信息是不是可以完全确定Query的执行计划,如果没有Hint,或者Hint不足以完全确定执行计划,则会读取所涉及对象的统计信息,根据Query进行写相应的计算分析,最后得出执行计划,这个过程,需要了解的重点是,Optimizer解析的结果和我们预期的结果不一定一样!

? ? ? ? 那Mysql是如何把自己认为最优的结果反馈给程序员或者DBA的呢,进而让Mysql更好的优化?

2、Mysql常见的性能瓶颈

? ? ? ? CPU方面:CPU在很繁忙的时候,一般是在数据装入内存或者从磁盘上读取数据的时候,Mysql得到的CPU处理的时间片,分配的线程就远远不够。

? ? ? ? IO:磁盘的IO也发生在装入的数据远大于内存导致磁盘IO高,Sql就会很慢,哪怕是一个最简单的查询语句。

? ? ? ? 服务器性能瓶颈,可以通过top,free,iostat,vmstat看下服务器的当前状态,是否需要升级配置。

3、Explain执行计划

? ? ? ? 概念:使用 EXPLAIN 关键字可以模拟优化器执行 SQL 查询语句,从而知道 MySQL 是如何处理你的SQL 语句的,进而分析你的查询语句或是表结构的性能瓶颈。

????????Explain能干这些事情:

  • 表的读取顺序
  • 数据读取的操作类型
  • 哪些索引可以使用
  • 哪些索引实际被使用
  • 表之间的引用
  • 每张表有多少行被优化器查询

????????用法: Explain+SQL 语句

? ? ? ? 假设我有个部门表:tbl_emp

? ? ? ? 执行下这个sql可以看出来:

? ? ? ? ?这些字段包含的什么意思呢,通过这些字段怎么能知道我当前的sql执行是什么样的,需不需要优化?怎么玩?

3.1、id

? ? ? ? 概念:select查询的序列号,包含一组数字,表示查询中执行的select子句或者操作表的顺序,重点:子句+操作顺序

? ? ? ? 场景:

? ? ? ? id相同,执行顺序由上至下

? ? ? ? 比如这个sql:explain select t2.* from t1, t2, t3 where t1.id = t2.id and t1.id = t3.id and t1.other_column = '';? ? ? ??

? ? ? ? 这个Sql你认为的from 顺序是t1,t2,t3,但是不然,Mysql自己认为的是t1,t3,t2这样的顺序,所以当id相同时,执行顺序由上至下!

? ? ? ? id不同的时候,如果是子查询,id的序号递增,id值越大优先级越高,越先被执行

? ? ? ? 比如这个sql:看下select_type列,有个subquery是子查询的意思,id=2和3的子查询,序号递增,优先级越高越先被执行,所以执行顺序是t3, t1, t2;并且仔细看这个sql,子查询正常会优先被执行,里面的结果出来,才会执行外面的。

? ? ? ? id既有相同,也有不同,同时存在的时候;永远是数字大的优先级最高,遇到相同id,自上而下顺序执行。

? ? ? ? 比如这个sql:因为执行计划中既有id相同,又有id不同,此时记住数字大的优先级最高,所以先执行id=2,对应的表是t3表,其实对于sql,这个刚好是内部的子查询先执行;然后对于id相同的两个id=1,顺序至上而下,先是table表为<derived2>,derived意思是衍生表的意思,后面的数字2表示从id=2这个表t3衍生出来的,仔细看sql,from的子查询,别名叫s1,这个是衍生表,来源于t3表,这样就好理解了,然后继续执行t2表,这就是执行顺序的分析。

? ? ? ? 所以这句话应该就可以明白Explain可以干的第一件事:

3.2、select_type

? ? ? ? 概念:查询的类型,主要是用于区别普通查询,联合查询,子查询等复杂查询;

? ? ? ? 有这些属性:simple,primary,subquery,derived,union,union result。

? ? ? ? simple:简单的select查询,查询中不包含子查询或者union

? ? ? ? primary:查询中若包含任何复杂的子部分,最外层查询则被标记为primary,通常理解为外层查询

? ? ? ? subquery:在select或者where列表中包含了子查询

? ? ? ? derived:在from列表中包含的子查询被标记为derived(衍生)Mysql会递归执行这些子查询,把结果放在临时表里。

? ? ? ? union:若第二个select出现在union之后,则被标记为union,若union包含在from子查询,外层的select则被标记为derived。

? ? ? ? union result:从union表获取结果的select。

? ? ? ? 所以Explain也起到这个作用:


3.3、table

? ? ? ? 这里就不说了,表示当前的表,或者是衍生表

3.4、type

? ? ? ? 概念:访问类型排列,显示查询使用了何种类型,最好到最差的状态依次是,

????????system? ?>? const? ?>? ?eq_ref? ?>? ?ref? ?>? ?range? ?>? ?index? ?>? ?All

????????还有一些我没标出来,目前我是基本没接触到除了上面这些之外的,用到再去了解吧。

? ? ? ? 如果发现ALL,且你的数据在百万级别以上,请你务必优化,因为ALL全表扫描!!但是你的记录只有10条,你说要不要?那没必要,不要为了优化而优化,形成过度优化。

? ? ? ? system:表只有一行记录,等于系统表,这个开发中,别指望了。

? ? ? ? const:表示通过索引一次就找到了,const用于比较primary key或者unique索引,因为这个只匹配一行数据,所以很快;比如将主键查询放在where后,就可以迅速的将该查询转为一个常量。

? ? ? ? 比如这个sql,t1表执行后,是const,因为id主键条件在where后面。

? ? ? ? eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配,常见于主键或者唯一索引扫描。

? ? ? ? 比如这个sql,先查t2表,查到一条与t1.id记录相匹配的一条记录,这个时候,会走eq_ref,这里和const有点类似,但是又不一样,const着重强调主键索引,但是这个强调在某个表中,这个索引键id,其他表中只有一条记录可以匹配;比如查一个公司的ceo,只有一条记录匹配。

? ? ? ? ?ref:非唯一性索引扫描,返回匹配某个单独值的所有行。本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以它应该属于查找和扫描的混合体。

? ? ? ? 比如这个sql:对表建立了复合索引,执行计划col1='ac'这个记录,和上面eq_ref不同的是,返回的是这个col列的所有等于ac的所有行,这个col的索引,是非唯一性索引,值不是唯一的,比如类似name='zhangsan'的人有很多行。

? ? ? ? range:只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引,一般就是在你的where语句中出现了between、<、>、in等查询,这种范围扫描索引,比全表扫描要好,因为它只需要开始于索引的某一点,而结束于另一个点,不用扫描全部索引;

? ? ? ? 比如这个sql:查between and的范围,还有in某个范围,type的属性都为range。? ? ? ? ?index:Full Index Scan,index与ALL的区别为index类型只遍历索引树,这通常比ALL快,因为索引文件通常比数据文件小,也就是说虽然ALL和Index都是读全表,但是Index是从索引中读取的,而all是从硬盘中读取;需要遍历整个索引树,就像你翻字典,不像上面可以直接定位查字母,而是从A查到Z,一个一个字母索引查,直到查到对应的索引;

? ? ? ? 比如这个sql:id已经是索引,查t1表的所有id字段,是不是要遍历整个索引表。

? ? ? ? ALL:Full Table Scan,将遍历全表以找到匹配的行。

? ? ? ? 最明显的sql,什么索引都没有,select * from t1; 几百万甚至上亿的数据,直接裂开!? ?

? ? ? ? 一般来说,保证查询至少到达range级别,最好能达到eq_ref。


3.5、possible_keys和key

? ? ? ? 概念:possible_keys显示可能应用在这张表上的索引,一个或者多个,查询涉及到的字段若存在索引,则该索引会被列出,但是不一定被查询使用!!!

? ? ? ? key是实际在Mysql自己认为这条sql,真正实际用到的索引是什么,如果为NULL,则没有使用索引,若查询中使用了覆盖索引,则该索引仅出现在key列表中!

? ? ? ? 比如像这种理论上用到了2个索引,实际上只用到一个索引的情况也很常见。

? ? ? ? 什么是覆盖索引呢?

? ? ? ? 来看个经典的场景:理论上没有用到索引,为NULL,但是实际上key用到这个索引idx_col1_col2,这个就描述了刚刚的话,若查询中使用了覆盖索引,则该索引仅出现在key列表中,简单说来,覆盖索引就是你查的字段个数,顺序和索引一模一样;查col1,col2,和建立当前这个复合索引的个数,顺序,一一对应,这个索引是

? ? ? ? create index idx_col1_col2 on t1(col1, col2);

?3.6、key_len

? ? ? ? 概念:表示索引中使用的字节数,可以通过该列计算查询中使用的索引长度,在不损失精确性的情况下,长度越短越好,key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_ken是根据表定义计算而得,不是通过表内检索出的。

? ? ? ? 有个例子,比如我要通过相亲的信息来找对象,目前我只知道性别,筛选了一批女性,这个时候索引长度假如为2,那不能是个女的就可以,我要身材好的,那我再加个索引,查出来了一批,这个时候索引长度为6,依次下去当我想要更多的信息,精度越精细,得到最后一个属于我的女人的时候,这个时候索引长度会很长,有点类似时间换空间的概念。

? ? ? ? 这个图就类似我举的例子

3.7、ref

? ? ? ? 概念:显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或者常量被用于查找索引列上的值。

? ? ? ? 什么意思呢?看这个图,t1先加载后,这个ref值是const常量,对应sql的条件是t1.other_column=一个常量值,t2和t3表示引用test库下的t1表下的ID字段;

? ? ? ? 再回顾之前的Explain能做什么,是不是也恍然大明白。

3.8、rows

? ? ? ? 概念:根据表统计信息以及索引选用情况,大致估算出找到所需的记录所需要读取的行数。

? ? ? ? 比如这个sql,t2表是没有索引的;看下这个where后面的t1.id = t2.id这个是eq_ref唯一性扫描,只有一行匹配,再看下t2.col1='ac';所以没建立索引的时候,一共要找640+1行才可以找到结果;

? ? ? ? ?如果加了索引呢?给t2加了索引后,整个查找的行数变成了142+1,可想而知,索引加了后,需要读取的行越少,效果越好!

? ? ? ? ?这也印证了上面最后一个Explain的点:

3.9、Extra

? ? ? ? 概念:包含不适合在其他列中显示但十分重要的信息;

? ? ? ? Extra的值有这些:Using filesort,Using temporary,Using where,Using index

? ? ? ? Using filesort:说明Mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取,Mysql中无法利用索引完成的排序操作称为“文件排序”。

? ? ? ? 我一直有说,索引等于排序+查找,Mysql说你给我建立了索引,我按照你说的方式去建立楼层,索引,我原本要按照这个顺序,可是在某种情况下我却用不到你给的索引,那么我只能另起炉灶,把这些顺序自己内部再排序一次。开发中遇到这个filesort,几乎就很坑爹,甚至九死一生,查询巨慢基本可以导致功能不可用。

? ? ? ? 举个例子,我这里有个sql,已经让Mysql建立好索引,idx_col1_col2_col3,比如1楼2楼3楼这么建楼,查询中有col1,where条件也有col1='ac',1楼用到了,所以type=ref引用了索引,ref字段是个const因为用到了常量ac,但是这个Extra字段出现了Using filesort!!!

? ? ? ? 原因是这样的,不好意思,你给的索引Mysql在检索方面,已经部分使用到了,而在排序的order by col3,Mysql没有用到,而索引增加的是检索和排序的优化,排序为什么Mysql用不到,排序的时候最好遵守所建索引的个数和顺序!!所以问题出现在这,索引顺序是1.2.3,但是你条件和排序后面跟的是1,3,2断层了!

? ? ? ? ?再对比个sql,order by后面是col2,col3,所以条件+排序整个的顺序和个数,刚好符合1楼,2楼,3楼这样的索引顺序;此时filesort没了,后者性能,高于前者!如果可以,尽快优化!

????????Using temporary:在filesort是九死一生,在这个temporary就更严重了,前者只是帮你内部排了个序,后者帮你建立了个内部的临时表!可能要为你处理一些数据先拷贝到临时表里再去折腾,再删除临时表!常见于排序order by和分组查询group by。

? ? ? ? 看个例子,这个sql索引一定用到,只要key这个字段不为NULL,group by后面直接到col2这个字段了,会有人问,哎前面的where查询不是有了col的条件吗,这个我后面会说,在索引中,范围查找会失效,那么就等价于前面的where col1 in...这个1楼失效了,你让我直接group by 2楼去分组,我当然就走不到索引上了,所以自然而然产生了filesort,还有temporary。

? ? ? ? ?我们可以这么优化,取消了临时表的创建,临时表的存在,是非常耗性能的!!

? ? ? ? ?Using index:这个指标是非常好的,表示相应的select操作中使用了覆盖索引,避免访问了表的数据行,效果不错,如果同时出现了Using where,表明索引被用来执行索引键值的查找,如果没有同时出现Using where,表示索引用来读取数据而非执行查找动作。

? ? ? ? 看看这个sql:哥们我建立的索引是1和2,你只查2说明你用到了部分索引 。如果同时出现了Using where,表明索引被用来执行索引键值的查找。

? ? ? ? 再看这个sql:如果没有同时出现Using where,表示索引用来读取数据而非执行查找动作。这个sql就是读取数据,没有where条件;

? ? ? ? 覆盖索引再完善下概念:查询的列要被所建的索引覆盖!!或者部分满足,比如我建立col1和col2,我只查1或者2,也是覆盖索引的一种!!

? ? ? ? 注意:如果要使用覆盖索引,一定要注意select列表中只列出需要的列,不可写select *,因为如果将所有的字段一起做索引,会导致索引过大,性能查询下降!!

? ? ? ? 这三个最重要的字段,是调优中最常见且最重要的,希望大家掌握!!其他不重要的我这里就不多阐述了,用到再查吧。

? ? ? ? 本章介绍了Explain的详细知识点,下一章节开始拿案例进行调优!!

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-10-29 13:06:54  更:2021-10-29 13:08:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:33:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码