盘点导致sql执行速度慢的几种情况,都是生产环境踩过的坑
当我们遇到慢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执行速度慢会受到很多种情况的影响,比如表锁,行锁。在实际的业务场景中也许会更复杂,但是处理起来的步骤基本大同小异,只要找到问题的根源,知道如何解决,处理起来就可以做到心中有数,游刃有余。
写文不易,朋友们帮忙点点赞和关注吧,多谢。
来源地址:https://blog.csdn.net/qq_33312725/article/details/128010225
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341