MySQL优化---常见的性能瓶颈以及Explain详解

一、MySQL常见性能瓶颈

CPU方面:SQL中对大量数据进行比较、关联、排序、分组。

IO方面:实际内存满足不了缓存数据或排序等需要,导致产生大量的物理I/O操作。

锁:不适宜的锁设置,导致线程阻塞性能下降。死锁,线程之间交叉调用资源导致死锁,程序卡住。

服务器硬件的性能瓶颈:可以通过top free iostat 和 vmstat来查看系统的性能状态。

二、Explain

1.Explain是什么?

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

2.怎么用?

Explain + SQL语句

执行计划包含的信息

1)id:select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序
①如果id相同,执行顺序由上至下  
此例中 先执行where 后的第一条语句 t1.id = t2.id 通过 t1.id 关联 t2.id 。 而  t2.id 的结果建立在 t2.id=t3.id 的基础之上。
 
 

②如果id不同,id值越大其执行优先级越高,越先被执行

③id相同和id不同的情况同时存在

id如果相同,可以认为是一组,从上往下顺序执行;
在所有组中,id值越大,优先级越高,越先执行

衍生表 = derived2 --> derived + 2 (2 表示由 id =2 的查询衍生出来的表。type 肯定是 all ,因为衍生的表没有建立索引)

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

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

②PRIMARY:查询中若包含任何的复杂查询,最外层查询则被标记为PRIMARY。

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

④SUBQUERY:在select或where列表中包含了子查询,且结果为一个值

⑤DEPENDENT SUBQUERY:在select或where列表中包含了子查询,且结果为多值。

⑥UNCACHEABLE SUBQUERY:无法被缓存的子查询

 @@为环境参数,所以无法缓存。

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

⑧UNION RESULT:从UNIOIN中获取结果的表

3)table:显示这一行的数据是关于哪张表的。

4)type:type显示的是访问类型,是较为重要的一个指标,结果值从最好到最坏依次是:

system>const>eq_ref>ref>range>index>ALL,一般来说,得保证查询至少达到range级别,最好能达到ref。

①system:这个查询的表只有一条记录,这是一个const类型的特例,平时不会遇到。

②const:表示通过索引一次就可以找到数据,const用于衡量primary key 或者unique索引。因为只匹配一行数据,所以执行效率很快。如将主键置于where列表中,MySQL就能将查询转换成一个常量。

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

④ref:非唯一性索引扫描,返回匹配某个单独值的所有行.本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行。

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

index:即Full Index Scan,index与all的区别为index类型只遍历索引树。(也就是说虽然all和Index都是读全表,但index是从索引中读取的,而all是从硬盘中读的

all:将通过遍历硬盘上的全表数据进行查找。效率最低

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

6)key:该查询真正使用到的索引,如果为null,则没有使用索引。且如果出现覆盖索引的情况,即当查询具体某一字段时,且那个字段有索引时,key 值会显示为索引。不懂看下图

7)key_len:表示索引中使用的字节数,key_len越大表明用到的索引越多,性能越好

8)ref:显示索引的哪一列被使用了。

emp这张表用了常量查询,dept这张表查询时用到了mytest数据库下的emp表的deptno索引。

9)rows:rows列显示MySQL认为优化器执行查询时必须检查的行数。越小越好。

10)包含不适合在其他列,但非常重要的信息 Extra

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

出现filesort的情况:

 
优化后,不再出现filesort的情况:(给 ename 加上了索引)

 
查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度
Using temporary:更不是什么好事。。使了用临时表保存中间结果,MySQL在对查询结果排序时使用临时表。常见于排序 order by 和分组查询 group by。如何优化?尽量group by 和 order by 的时候用索引字段,如果为复合索引需要将索引全用上。。

Using Index:这是好事!!表明相应的select操作中使用了覆盖索引,也就是说,直接在索引中进行查找。覆盖索引的意思是:假如建立了一个复合索引(col1,col2,col3),在查询的字段中如果是其子集,则会直接从索引文件中查找,不需要去数据文件中查找了。

当与 Using where 同时出现的时候,表明索引也被用来执行查找操作了。

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

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

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

⑦select tables optimized away

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

在inoodb中

在Myisam中

myisam 中会维护 总行数 (还有其他参数)这个参数,所以在执行查询时不会进行全表扫描。而是直接读取这个数。
但会对增删产生一定的影响。根据业务情况决定谁好谁坏
innodb 中没有这个机制。

发布了227 篇原创文章 · 获赞 77 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/m2606707610/article/details/103671315
今日推荐