19.执行单条记录查询慢的原因

先补充几条指令

①可以用 show processlist查看连接状态

show processlist

 

②可以用lock table 表名 WRITE/READ 来模拟指定加读锁还是写锁,用unlock tables来是释放锁

③查看占有锁的pid

SELECT blocking_pid FROM sys.schema_table_lock_waits

只查询一行语句,但是却很慢的原因(CPU占用率高,IO占用率高都不在这次的讨论范围内)

一.查询查询长时间不返回

1.等待MDL锁(元数据锁)

元数据锁是server层的锁,表级锁,主要用于隔离DML和DDL操作之间的干扰

DML操作只会申请MDL读锁,如果有其他线程获取了MDL写锁,则该线程在执行DDL操作

比如sessionA持有了表user的MDL写锁,此时sessionB对表user进行的操作会阻塞直到sessionA释放锁,可以用SELECT blocking_pid FROM sys.schema_table_lock_waits来查看阻塞的id,用kill命令断开连接即可释放锁

2.flush

Waiting for table flush状态的可能情况:flush命令被别的指令堵住了,然后这个flush命令来堵我们当前的命令

flush tables t with read lock; //锁指定表 flush tables with read lock; //锁所有表

flush操作正常情况下执行很快,除非他们被别的线程堵住了

解决方法:将堵住flush操作的线程结束,方法同1

3.等行锁

sessionA开启事务然后占用写锁且未提交,此时sessionB就会被困住

mysql5.7可以用来着看是哪张表占用了写锁

select * from t sys.innodb_lock_waits where locked_table='`test`.`t`'\G

还是一样用kill pic 来释放行锁

二.查询慢

其中一个原因是undolog过大导致一致性读回滚日志消耗太多时间

先看下面这个例子,第二条语句加了意向共享锁,但是却执行的更快,并且可以发现有加锁和没加锁读到的数据不一样(因为在这次两句sql所在的事务还未提交,但是别的事务已经把c加1加了100万次)

导致数据不一样的原因是:在可重复读的隔离级别下,在事务中带lock in share mode是当前读,不带的是一致性读,当前都可以直接读取到100001这个最新的数据,但是普通的select是一致性读,因此需要从 1000001 开始,依次执行 undo log,执行了 100 万次以后,才将 1 这个结果返回。

(回归日志过大导致一次读慢,当前读快)

 

 

在可重复读隔离级别下,consistent snapshot才有意义

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值