SQL语句为什么执行的很慢?
一条 SQL 语句执行的很慢,那是每次执行都很慢呢?还是大多数情况下是正常的,偶尔出现很慢呢?所以我觉得,我们还得分以下两种情况来讨论。
大多数情况是正常的,只是偶尔会出现很慢的情况。
在数据量不变的情况下,这条SQL语句一直以来都执行的很慢。
一、针对偶尔很慢的情况
1、数据库在刷新脏页
当我们要往数据库插入一条数据、或者要更新一条数据的时候,我们知道数据库会在内存中把对应字段的数据更新了,但是更新之后,这些更新的字段并不会马上同步持久化到磁盘中去,而是把这些更新的记录写入到 redo log 日记中去,等到空闲的时候,在通过 redo log 里的日记把最新的数据同步到磁盘中去。
不过,redo log 里的容量是有限的,如果数据库一直很忙,更新又很频繁,这个时候 redo log 很快就会被写满了,这个时候就没办法等到空闲的时候再把数据同步到磁盘的,只能暂停其他操作,全身心来把数据同步到磁盘中去的,而这个时候,就会导致我们平时正常的SQL语句突然执行的很慢,所以说,数据库在在同步数据到磁盘的时候,就有可能导致我们的SQL语句执行的很慢了。
2、拿不到锁
这个就比较容易想到了,我们要执行的这条语句,刚好这条语句涉及到的表,别人在用,并且加锁了,我们拿不到锁,只能慢慢等待别人释放锁了。或者,表没有加锁,但要使用到的某个一行被加锁了,这个时候,我也没办法啊。
如果要判断是否真的在等待锁,我们可以用 show processlist这个命令来查看当前的状态哦,这里我要提醒一下,有些命令最好记录一下,反正,我被问了好几个命令,都不知道怎么写,呵呵。
下来我们来访分析下第二种情况,我觉得第二种情况的分析才是最重要的。
二、针对一直都这么慢的情况
1、没用到索引
1)字段没有索引
2)字段有索引,但却没有用索引
3)函数操作导致没有用上索引
2、数据库自己选错索引
以上是我的总结与理解,最后一个部分,我怕很多人不大懂数据库居然会选错索引,所以我详细解释了一下,下面我对以上做一个总结。
一个 SQL 执行的很慢,我们要分两种情况讨论:
大多数情况下很正常,偶尔很慢,则有如下原因:
数据库在刷新脏页,例如 redo log 写满了需要同步到磁盘。
执行的时候,遇到锁,如表锁、行锁。
这条 SQL 语句一直执行的很慢,则有如下原因:
没有用上索引:例如该字段没有索引;由于对字段进行运算、函数操作导致无法用索引。
数据库选错了索引。