当前位置:   article > 正文

为什么会出现慢SQL_慢sql 什么时候会出现

慢sql 什么时候会出现

为什么会出现慢SQL

在生产环境中,慢SQL是一个比较严重的问题,在面试时也会经常被问到,那究竟哪些情况会产生慢SQL,我们又该如何排查,如何定位呢?接下来我们将一步步带来这些问题的答案

写操作

刷脏页

脏页的定义是这样的:内存数据页和磁盘数据页不一致时,那么称这个内存数据页为脏页。

对于一条写操作的 SQL 来说,执行的过程中涉及到写日志,内存及同步磁盘这几种情况

在写操作时,InnoDB会将记录写入到 redo log 中,并更新缓存,这样更新操作就算完成了。后续操作存储引擎会在适当的时候(buffer pool满了或者redo log满了)把操作记录同步到磁盘里

因为写redo log 的过程是顺序写磁盘的,磁盘顺序写减少了寻道等时间,速度比随机写要快很多( 类似Kafka存储原理),因此写 redo log 速度是很快的

在磁盘中,redo log 顺序存储在两个文件中,大小是一定的,且是循环写入的。在高并发场景下,redo log 很快被写满了,但是数据来不及同步到磁盘里,这时候就会产生脏页,并且还会阻塞后续的写入操作。SQL 执行自然会变慢

写操作时 SQL 慢的另一种情况是可能遇到了锁,当某一条 SQL 所要更改的行刚好被加了锁,那么此时只有等锁释放了后才能进行后续操作。

但是还有一种极端情况,如果遇到了死锁或是锁等待的情况。这时候该如何处理呢?

Mysql 中提供了查看当前锁情况的方式:
在这里插入图片描述
通过在命令行执行图中的语句,可以查看当前运行的事务情况

在这里插入图片描述
当前事务如果等待时间过长或出现死锁的情况,可以通过 「kill 线程ID」 的方式释放当前的锁。

这里的线程 ID 指表中 trx_mysql_thread_id 参数。

读操作

定位慢SQL

定位慢SQL的常用方法是查看慢查询日志,它是用来记录超过指定时间的 SQL 语句的。默认情况下是关闭的,通过手动配置才能开启慢查询日志进行定位。
临时开启的语句是

set global slow_query_log=“ON”;

如果需要长期开启就需要改sql的配置文件my.cnf

存在原因

知道了如何查看执行慢的 SQL 了,那么我们接着看读操作时为什么会导致慢查询
(1)未命中索引SQL 查询慢的原因之一是可能未命中索引,关于使用索引为什么能使查询变快以及使用时的注意事项,网上已经很多了,这里就不多赘述了
(2)脏页问题另一种还是我们上边所提到的刷脏页情况,只不过和写操作不同的是,是在读时候进行刷脏页的

为什么读操作也会刷脏页

为了避免每次在读写数据时访问磁盘增加 IO 开销,Innodb 存储引擎通过把相应的数据页和索引页加载到内存的缓冲池(buffer pool)中来提高读写速度。然后按照最近最少使用原则来保留缓冲池中的缓存数据。

那么当要读入的数据页不在内存中时,就需要到缓冲池中申请一个数据页,但缓冲池中数据页是一定的,当数据页达到上限时此时就需要把最久不使用的数据页从内存中淘汰掉。但如果淘汰的是脏页呢,那么就需要把脏页刷到磁盘里才能进行复用,接下来就是刷脏页的操作了,因而在高并发环境下可能会导致慢SQL。

如何排查慢SQL

索引命中

通常用的方法是查看执行计划,方法也很简单,就是在所执行的 SQL 前加上 explain 就可以来分析当前 SQL 的执行计划,重要的几个字段包括type查询的方式,possible_keys可能的索引,key实际的索引,rows查找的行数,Extra其他重要信息,主要看有没有用覆盖索引Using index

刷脏页

对于刷脏页的情况,我们需要控制脏页的比例,不要让它经常接近 75%。同时还要控制 redo log 的写盘速度,并且通过设置 innodb_io_capacity 参数告诉 InnoDB 你的磁盘能力,从而避免脏页落盘阻塞产生的慢SQL问题

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/1006672
推荐阅读
相关标签
  

闽ICP备14008679号