写点什么

盘点导致 sql 执行速度慢的几种情况,都是生产环境踩过的坑

作者:程序员拾山
  • 2023-02-13
    河南
  • 本文字数:998 字

    阅读完需:约 3 分钟

当我们遇到慢 sql,第一反应可能就是去优化我们的 sql 语句。一些比较复杂的语句如果执行慢可能还能理解,但是有时一些特别简单的查询也会变得卡顿,“查一行”,也会执行得特别慢。今天,我们盘点一下,都有哪些情况会导致 sql 执行速度慢。

1,数据库本身压力较大


如果数据库本身的性能压力就比较大,资源比较紧张,CPU 占用率或者 IO 利用率很高,这时会导致所有的语句执行起来都比较慢。这种情况下首先要做的应该是提升服务器的配置,然后观察服务器的性能指标是否平稳。



2,表锁冲突


如果遇到一个简单的查询长时间未返回结果,那么大概率是表被锁住了。一般遇到这种情况,都是通过 show processlist 命令,查看 sql 语句的状态。



如图所示,id 为 8 的语句正在等待一个 MDL 锁,我们可以使用 kill 命令杀掉这个阻塞线程。


另外还可以通过表 sys.schema_table_lock_waits 查询阻塞的线程 id。



3,行锁冲突

mysql> select * from temp where id =3 for update;
复制代码


当我们访问 id=3 这条记录时,使用了 for update,表示要对这条语句加锁。但是如果此时已经有另一个事务对这条记录加了锁,并且一直持有不释放锁,那么当前语句就会一直阻塞。



通过上图可以看出,第一个语句不提交事务,第二个语句就一直处于等待阻塞状态。


我们执行 show processlist,



可以看出确实有一个线程处于阻塞状态。


锁冲突会导致执行效率降低,进而影响到业务,需要我们重点关注。

4,索引未命中

mysql> select * from t where c=50000 limit 1;
复制代码


如果字段 c 上面没有索引,那么就只能走主键 id 顺序扫描,一直扫描到第 50000 行才能停下来。


给表数据加索引可以快速提升查询性能,一般来说,因为索引失效导致的慢 sql 可能是我们平常开发过程中经常遇到的,比如字段类型的隐式转换,字段使用了函数导致索引失效等等。

5,多表 join 查询


有了索引,并不代表万事大吉。如果一个比较复杂的 sql,需要关联很多表进行查询,即使每张表的索引都可以起到作用,但是由于数据量过多,即使都命中索引,扫描的行数仍然是巨大的。这样 sql 的执行速度仍然会受到很大影响。


一般来说,超过 3 个表的 join 就应该尽量避免,将其拆分为多个查询,使用空间换时间也不失为一个好办法。

总结


总的来说,sql 执行速度慢会受到很多种情况的影响,比如表锁,行锁,索引失效等。在实际的业务场景中也许会更复杂,但是处理起来的步骤基本大同小异,只要找到问题的根源,知道如何解决,处理起来就可以做到心中有数,游刃有余。


finally,都看到这里了,点个赞再走吧。

发布于: 刚刚阅读数: 5
用户头像

JAVA技术分享,全网同名 2019-06-19 加入

学习如逆水行舟,不进则退

评论

发布
暂无评论
盘点导致sql执行速度慢的几种情况,都是生产环境踩过的坑_MySQL_程序员拾山_InfoQ写作社区