当前位置:网站首页 > SQL数据库编程 > 正文

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



首先要执行下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得到他能看到的数据版本,要不断回滚,这就导致了查询时间过长。

到此这篇mysql主键查询慢(mysql怎么看主键)的文章就介绍到这了,更多相关内容请继续浏览下面的相关 推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • sql循环语句的几种写法(sqlfor循环语句)2026-05-13 18:09:08
  • 使用pymysql连接数据库(pymysql连接数据库并且增删改查封装)2026-05-13 18:09:08
  • sql窗口函数 文档下载不了(sql窗口函数 文档下载不了怎么回事)2026-05-13 18:09:08
  • sql文件怎么导入mysql(sql文件怎么导入sqlyog)2026-05-13 18:09:08
  • mysql 主键重置为0(mysql修改主键字段的值)2026-05-13 18:09:08
  • pycharm安装pymysql包(pycharm如何安装pygame库)2026-05-13 18:09:08
  • mysql主键约束怎么写(mysql主键约束语句)2026-05-13 18:09:08
  • mysql中主键可以为空吗(mysql主键语句)2026-05-13 18:09:08
  • mysql 和 oracle(mysql和oracle的分页查询的区别)2026-05-13 18:09:08
  • pymysql用法(pymysql whl)2026-05-13 18:09:08
  • 全屏图片