MySQL 执行慢原因分析
Posted BBinChina
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL 执行慢原因分析相关的知识,希望对你有一定的参考价值。
SQL执行慢不外乎以下原因:
1、查询语句设计不合理。简单的 SQL 语句执行效率高,复杂的 SQL 语句执行效率低。
2、索引处理不当,如忘记在 WHERE 后面加上索引,导致查询过程中无法使用索引来特别优化查询。
3、表没有做合理的分区。
在实践过程中,我们可以根据多变的情况进行逐步分析:
情况分析
在生产环境中,相同数据量情况下,有SQL偶尔执行慢即出现频率低,也有SQL每次执行都慢即出现频率高。
出现频率低情景
1、InnoDB脏页刷新
Innodb为了优化写效率,采用了内存缓冲及redo log(写磁盘)的方式,当内存页与磁盘页数据不一致时(脏页),mysql会进行刷盘(定时批量)。或者mysql dump之后,从redo log恢复最新数据。
redo log是有容量的,如果数据库操作频繁,redo log会写满,那么需要写到磁盘,而不能等到空闲的时候做刷盘了,这个时候必须停止其他操作,因此正在执行的操作就会执行得慢。
2、操作等待锁资源
当我们在update数据时,需要获取行锁,行锁为悲观锁。当行锁被其他事务获取时,当前事务需要等待,直到行锁被释放。
出现频率高情景
-
SQL执行没有走索引
1、SQL执行时的where没有使用索引,进行全表查询,当数据量大时,执行效率低
2、SQL执行时where里使用了索引,那么通过explain进行分析
如果where条件中对索引字段进行运算操作或者函数操作,SQL执行时不会触发索引执行。 -
SQL的执行走索引
1、通过explain分析,虽然走了索引,但类型为all,表明依然走的是全表查询
场景有:
使用了前缀模糊匹配 like,不能命中索引
= 前的索引列上进行了表达式运算
数据表中 phone 字段是字符串类型,而查询时使用了数字类型,会触发隐式类型转换,不会命中索引
2、根据索引查找的机制进行分析,从辅助索引查找到数据主键时,在通过聚簇索引找到行数据,如果索引不能有效的区分数据,比如像年龄,不能区分大部分数据时(年龄分布平均)
mysql会根据这个预测分析通过全表查询(遍历行数据)会比通过索引效率高(先通过辅助索引,再通过聚簇索引分析行数据)
3、单表数据量超过千万后,性能会出现下降(b+tree数据结构缺点)
以上是关于MySQL 执行慢原因分析的主要内容,如果未能解决你的问题,请参考以下文章