Mysql性能分析

2021/4/18 2:26:50

本文主要是介绍Mysql性能分析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1.Mysql Query Optimizer

mysql中有专门负责优化select语句的优化器模块,主要功能:通过计算分析系统中收集到的统计信息,为客户端请求的query提供他认为最优的执行计划(mysql认为的最优数据检索方式,不见得是DBA认为最优的,这部分最耗时间)。

当客户端向mysql请求一条query,命令解析器模块完成请求分类,区别出是select并转发给mysql query optimizer时,mysql query optimizer首先会对整条query进行优化,处理掉一些常量表达式的预算,直接换算成常量值。并对query中的查询条件进行简化和转换,如去掉一些无用或显而易见的条件、结构调整等。然后分析query中的Hint信息(如果有),看显示Hint信息是否可以完全确定该query的执行计划。如果没有Hint或Hint信息还不足以完全确定执行计划,则会读取所涉及对象的统计信息,根据query进行写相应的计算分析,然后再得出最后的执行计划。

2.Mysql常见瓶颈

CPU:cpu在饱和的时候一般会发生在数据装入内存或从磁盘上读取数据时

IO:磁盘IO瓶颈发生在装入数据远大于内存容量的时候

服务器硬件的性能瓶颈:top,free,iostat,vmstat来查看系统的性能状态

3.Explain

SQL的执行计划,使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理SQL语句的。

语法:explain+sql

执行计划包含的信息

在这里插入图片描述

字段解释:

id:决定表的读取顺序

id是select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序

包含以下三种情况:①id相同,执行顺序由上至下;②id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行;③id相同和不同,同时存在,永远是id大的优先级最高,id相等的时候顺序执行。

select_type:决定数据读取操作的操作类型

select_type是查询的类型,主要是用于区别普通查询、联合查询、子查询等的复杂查询。

常用的值有

SIMPLE:简单的select查询,查询中不包含子查询或者UNION

PRIMARY:查询中若包含任何复杂的子部分,最外层查询则标记为PRIMARY

SUBQUERY:在select或where列表中包含了子查询

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

UNION:若第二个select出现在union之后,则被标记为union;若union包含在from子句的子查询中,外层select将被标记为:DERIVED

UNION RESULT:从UNION表获取结果的select

table

显示这一行的数据是关于哪张表的

type

显示查询使用了何种类型

访问类型排列
在这里插入图片描述

从最好到最差依次是:

system>const>eq_ref>ref>range>index>ALL

system:表只有一行记录(等于系统表),这是const类型的特例,平时不会出现,这个也可以忽略不计。

const:表示通过索引一次就找到了,const用于比较primary key或者unique索引。因为只匹配一行数据,所以很快。如将主键置于where列表中,MySQL就能将该查询转化为一个常量。

eq_ref:唯一性索引扫描,读取本表中和关联表表中的每行组合成的一行,查出来只有一条记录。除 了 system和const类型之外, 这是最好的联接类型。

ref:非唯一性索引扫描,返回本表和关联表某个值匹配的所有行,查出来有多条记录。

range:只检索给定范围的行,一般就是在WHERE语句中出现了BETWEEN、< >、in等的查询。这种范围扫描索引比全表扫描要好,因为它只需要开始于索引树的某一点,而结束于另一点,不用扫描全部索引。

index:Full Index Scan,全索引扫描,index和ALL的区别为index类型只遍历索引树。也就是说虽然ALL和index都是读全表,但是index是从索引中读的,ALL是从磁盘中读取的。

ALL:Full Table Scan,没有用到索引,全表扫描。

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

possible_keys:决定哪些索引可以使用

显示可能应用在这张表中的索引,一个或者多个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用

key:决定哪些索引被实际使用

实际使用的索引。如果为NULL,则没有使用索引。查询中如果使用了覆盖索引,则该索引仅仅出现在key列表中。

如果索引包含所有满足查询需要的数据的索引成为覆盖索引(Covering Index)。

key_len

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

ref:决定表之间的引用

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

rows:决定每张表有多少行被优化器查询

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

Extra

包含不适合在其他列中显示但十分重要的额外信息。

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

②Using temporary:使用了临时表保存中间结果,MySQL在対查询结果排序时使用了临时表。常见于排序order by和分组查询group by。临时表対系统性能损耗很大。

③Using index:表示相应的SELECT操作中使用了覆盖索引,避免访问了表的数据行,效率不错!如果同时出现Using where,表示索引被用来执行索引键值的查找;如果没有同时出现Using where,表明索引用来读取数据而非执行查找动作。

覆盖索引:select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。

注意:如果要使用覆盖索引,一定不能写SELECT *,要写出具体的字段。

④Using where:表明使用了where过滤

⑤Using join buffer:使用了连接缓存

⑥impossible where:where子句的值总是false,不能用来获取任何元组

⑦select tables optimized away:在没有group by子句的情况下,基于索引优化MIN/MAX操作或者对于MyISAM存储引擎优化count(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化

⑧distinct:优化distinct操作,在找到第一匹配的元组后即停止找同样值的动作

4.Join优化

尽可能减少JOIN语句中的NestedLoop(嵌套循环)的总次数:永远都是小的结果集驱动大的结果集

优先优化NestedLoop的内层循环。

保证JOIN语句中被驱动表上JOIN条件字段已经被索引。

当无法保证被驱动表的JOIN条件字段被索引且内存资源充足的前提下,不要太吝惜Join Buffer 的设置。

个人笔记,仅用于分享学习,资料都是从尚硅谷的视频教程中学习总结。



这篇关于Mysql性能分析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程