一、开始装逼:分类讨论
1.大多数情况是正常的,只是偶尔会出现很慢的情况。
2.在数据量不变的情况下,这条SQL语句一直以来都执行的很慢。
二、针对偶尔很慢的情况
一条SQL大多数情况正常,偶尔才能出现很慢的情况,针对这种情况,我觉得这条SQL的书写本来是没有问题的,而是其他原因导致,那会是什么原因呢?
1.数据库在刷新4脏页(flush)我也无奈啊
当我们要往数据库插入一条数据、或者更新一条数据的时候,我们知道数据会在内存中把对应字段的数据更新了,但是更新之后,这些更新的字段并不会马上同步持久到磁盘中去,而是把这些更新的记录写入到redo log日记中去,等到空闲的时候,再通过redo log里的日历把最新的数据同步到磁盘中去。
刷新脏页有下面4种场景(后两种不用太关注“性能问题”):
1.Redolog写满了:因为执行sql的更新语句的时候,如果更新很多的话,很有可能relog里面有很多语句都处于commit状态,还未到从内存提取到硬盘去,所以这边想进入redolog的prepare状态是不行的,要等redolog里面的内容执行完后(SQL语句慢),才会执行新的更新语句。
2.内存不够:如果一次查询较多的数据,恰好所要查询的数据页不在内存中,需要把查询的内容从硬盘放入内存中,但是内存中是脏页,所以先要把内存中的脏页写入硬盘后,然后把硬盘中所需页取到内存中,去执行这个sql所需要的数据。
3.Mysql认为系统空闲:因为要从redo-prepare到commit,将内存的东西同步到硬盘,
4.MySQL正常关闭的时候:这时候,MySQL会把内存的脏页都flush到磁盘上,这样下次MySQL启动的时候,就可以直接从磁盘上读取诗句,启动速度会很快。
2.拿不到锁,我能怎么办
我们要执行表或者行操作的时候,别的进程在进行操作,所以只能等着别人释放,才能操作。
判断是否在等待锁,我们可以用show processlist这个命令来查看当前的状态。
三、针对一直都这么慢的情况
索引大宝贝没有用上
1.字段没有索引
如果字段没有索引,那么只有走全表扫描,把你等到花儿谢
2.字段有索引,但却没有用索引(左边运算了)
你给下面这个sql的c字段加了索引,但是用不到的。
因为左边做了运算,就不会用上索引!所以想用上索引,就要这样写:
3.函数操作导致没有用上索引
如果我们对字段进行函数操作后,也会导致没有用上索引。
呵呵,数据库自己选错索引了
如我们在进行查询操作的时候:
C的索引可以使主键索引或者是非主键索引。如果是主键索引那么直接查最快。但是如果c是非主键索引的话,那么就有一种可能:系统根据判断误走了全局查询。为什么呢?
因为非主键索引,索引所存的值是主键的值,所以用非主键索引查询他是需要两次查询的,然后系统评估非主键索引快还是全局扫描快。
为什么会有误判呢?
既然要误判,那我们首先先要把判断搞清楚:进行非主键索引的时候,系统会判断这个非主键索引的基数(基数:比如性别是索引,那么基数为2;如果骰子(六面)点数是索引,基数为6)。比如数基数很小,那么索引查出某个字段(比如男)那么也会查询出一半的数,那么索引就没有意义了。
所以,基数越大那么索引查询的效果越好!!然后根据基数的大小,系统选择用索引还是全表扫描。但是系统不可能去扫描全部的基数,只是采样计算!!那么采样就意味着是随机!!刚好这次采样结果是基数很小,所以就选择了全表扫描而不是索引,导致慢起来了。这就是统计随机的结果!
但是,我们可以强制走索引的方式来查询:
当然我们也可以去查询索引的基数
可查询出下列表格:
Cardinality是基数,如果和实际基数差距太大,那么可以用下面语句重新计算一次看看,然后再看索引。
因为选索引的时候会导致随机计算采样,所以当sql语句有多个索引的时候(mysql只能选择一个索引),如果我没有指定,那么只能由mysql的优化器自己去决定使用哪个索引,所以有可能mysql采样随机导致选错了索引,查询变慢。
四、总结
分为两种情况,偶尔比较慢和一直很慢
偶尔比较慢:
1.数据库在刷新4脏页(flush)
2. 拿不到锁,其他进行将表或者行一直锁着。
一直很慢:
1.没有用上索引
2.数据库自己判断,选错索引
手写高质量SQL的30条建议
B站视频讲解MySQL
https://www.bilibili.com/video/BV1FN411R7GJ
https://www.bilibili.com/video/BV1ar4y1K74C/
B站视频讲解如何三个月学习JAVA拿到实习Offer:
https://www.bilibili.com/video/BV1dV411t71K
更多Mysql知识笔记:
https://blog.csdn.net/qq_40262372/article/details/113435541
如果想要在学习的道路上和更多的小伙伴们交流讨论
请加Q群:725936761
欢迎每一位小伙伴的加入
我们一起朝着目标加油!冲锋陷阵!