为什么我只查询一行语句,也执行这么慢?

本文探讨了MySQL中查询长时间不返回的原因,包括表锁、行锁和等待flush的情况。通过showprocesslist和sys schema_table_lock_waits、sys.innodb_lock_waits表可以定位问题。同时,分析了带lockinsharemode与不带的查询差异,涉及回滚日志和一致性读的概念。了解这些机制有助于优化查询性能。
摘要由CSDN通过智能技术生成

第一类:查询长时间不返回
在这里插入图片描述
一般这种情况是表t被锁住了,首先需要执行以下show processlist命令,看一下语句处于什么状态。
1.等MDL锁在这里插入图片描述
出现这种状态代表一个线程正在表t上请求或者持有MDL写锁,把select语句堵住了。
由于通过show processlist查看到的结果中sessionA的command列处于sleep状态,导致查找起来不方便,所以可以通过查询sys.schema_table_lock_waits这张表,就可以直接找到阻塞的process id在这里插入图片描述
2.等flush
在这里插入图片描述
出现Waiting for table flush状态的可能情况是:有一个flush tables命令被别的语句堵住了,然后它又堵住了我们的select语句。

在这里插入图片描述
在这里插入图片描述
等行锁
由于访问id=1这个记录要加读锁,如果这时候已经有一个事务在这行记录上持有一个写锁,我们的select语句就会被堵住。
在这里插入图片描述
在这里插入图片描述
可以通过sys.innodb_lock_waits 表查到。
查询方法是:
mysql> select * from t sys.innodb_lock_waits where locked_table='test'.'t'\G

查询慢的情况
执行以下语句时长长达800ms

mysql> select * from t where id=1;

但是执行select * from t where id=1 lock in share mode却只用时0.2毫秒。
原因如下:
在这里插入图片描述

session B更新完100万次会生成100万个回滚日志(undo log)。
带lock in share mode是当前读,所以会直接读到1000001这个结果。而select * from t where id=1是一致性读,会从1000001开始执行undo log,执行了100万次以后,才将1这个结果返回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值