mysql主键查询慢(mysql怎么看主键)

mysql主键查询慢(mysql怎么看主键)首先要执行下 show processlist 来查看各个线程的状态 是否在等待锁 1 DML 写锁导致其他线程对改表的读取被阻塞 当一个线程正在持有 t 表的 DML 写锁时 其他线程查询语句就会被阻塞 一直等到 DML 写锁释放才能执行 这个 63870 上的线程的 state 是 waiting for table metadata

大家好,我是讯享网,很高兴认识大家。



首先要执行下show processlist来查看各个线程的状态(是否在等待锁)

1.DML写锁导致其他线程对改表的读取被阻塞

当一个线程正在持有t表的DML写锁时,其他线程查询语句就会被阻塞,一直等到DML写锁释放才能执行。

这个63870上的线程的state是waiting for table metadata lock,即在等待DML元数据锁的释放。

解决:使用查询语句查出是哪个过程在阻塞,使用kill命令断开这个连接即可

 

讯享网

2.等flush

我们执行select * from t_19 where id=1;这条查询语句时,一直不返回,检测processlist发现在等待flush。

从processlist中可以看出,有2个线程在等待flush,但是flush这个过程是很快的,为什么会阻塞住呢,因为这个flush线程想要flush时,发现有另一个线程正在执行查询,为什么这个线程在执行查询就会导致这个flush被阻塞?

FLUSH TABLE就是关闭打开的表,并且刷新查询缓存 ,如果有LOCK TABLES ... READ存在则不允许

但是从processlist可以看到,我的查询语句没有加读锁啊?


讯享网

原因是这3条语句是在3个事务中执行的,可重复读或者串行化的隔离级别下,select语句会加共享读锁

总的来说就是事务A中的select sleep(1) from t_19;语句导致这个表加了共享读锁,然后事务B中的flush tables t_19;语句就被阻塞住了,因为它想关闭表,但是事务A的查询语句还没执行完,最后事务C中的 select * from t_19 where id=1;这条普通查询就被阻塞住了,因为在等待flush。

解决:把第一个查询停止就行了

3.等行锁

一个查询语句会被另一个线程对同一行数据上所获取的写锁阻塞。

1.没加索引导致扫描行数太多

2.一致性读的时候,数据的版本太多,需要一直回滚到当前事务应该看到的数据版本,导致查询慢

事务A开始

事务B开始

事务B执行update t set c=c+1 where id =1(100w次)

事务A执行select c from t where id =1(执行800ms后,得到结果:c=1)

事务A执行select c from t where id =1 lock in share mode(执行0.2ms,得到结果:c=)

为什么第一个查询比第二个查询慢这么多?因为第二个查询加了s型锁,是当前读,直接读最新数据c=

而第一个查询是快照读,而事务B的插入语句的结果对于事务A是不应该可见的(事务B未提交并且事务B在事务A开始后才开始),并且这个语句执行了太多次,每次都生成一个undolog条目,所以对于事务A来说,要一直根据undo log得到他能看到的数据版本,要不断回滚,这就导致了查询时间过长。

小讯
上一篇 2025-04-21 10:18
下一篇 2025-06-09 08:45

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/159265.html