欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SQL 语句执行很慢的原因

程序员文章站 2022-05-01 20:56:56
大多数情况是正常的,只是偶尔会出现很慢的情况 网络问题 数据库在刷新脏页 获取锁失败,我们可以用 show processlist这个命令来查看当前的状态 刷脏页有下面4种场景(后两种不用太关注“性能”问题): redolog写满了:redo log 里的容量是有限的,如果数据库一直很忙,更新又很频 ......

大多数情况是正常的,只是偶尔会出现很慢的情况

  • 网络问题

  • 数据库在刷新脏页

  • 获取锁失败,我们可以用 show processlist这个命令来查看当前的状态

刷脏页有下面4种场景(后两种不用太关注“性能”问题):

  • redolog写满了:redo log 里的容量是有限的,如果数据库一直很忙,更新又很频繁,这个时候 redo log 很快就会被写满了,这个时候就没办法等到空闲的时候再把数据同步到磁盘的,只能暂停其他操作,全身心来把数据同步到磁盘中去的,而这个时候,就会导致我们平时正常的sql语句突然执行的很慢,alter table 可能造成脏页过多。所以说,数据库在在同步数据到磁盘的时候,就有可能导致我们的sql语句执行的很慢了。

  • 内存不够用了:如果一次查询较多的数据,恰好碰到所查数据页不在内存中时,需要申请内存,而此时恰好内存不足的时候就需要淘汰一部分内存数据页,如果是干净页,就直接释放,如果恰好是脏页就需要刷脏页。

  • mysql 认为系统“空闲”的时候/ master thread:这时系统io压力不大,每秒或每十秒的异步刷新操作

  • mysql 正常关闭的时候:这时候,mysql 会把内存的脏页都 flush 到磁盘上,这样下次 mysql 启动的时候,就可以直接从磁盘上读数据,启动速度会很快。

在数据量不变的情况下,这条sql语句一直以来都执行的很慢

  • 没有用上索引:例如该字段没有索引;由于对字段进行运算、函数操作导致无法用索引。
  • 数据库选错了索引

有索引但是最终却选择全表扫描的原因:

例如以下sql:

select * from t where 100 < c and c < 100000;

索引的选择判断来源于系统的预测,也就是说,如果要走 c 字段索引的话,系统会预测走 c 字段索引大概需要扫描多少行。如果预测到要扫描的行数很多(大概接近于20%),它可能就不走索引而直接扫描全表了。因为索引c将标识多一次的辅助索引的查询,造成io的增多。

系统判断是否走索引,扫描行数的预测其实只是原因之一,这条查询语句是否需要使用使用临时表、是否需要排序等也是会影响系统的选择的。