第十九章 为什么我只查一行的语句,也执行这么慢?

2024-01-03 16:48

本文主要是介绍第十九章 为什么我只查一行的语句,也执行这么慢?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第十九章 为什么我只查一行的语句,也执行这么慢?

查询长时间不返回

一条查询语句始终无返回,可能是因为什么原因导致的 ?

  • 可能在等待 MDL 锁 释放
    • 查询语句执行时申请的是 MDL 读锁,若之前有 MDL 写锁 处于申请中或正持有中,则MDL 读锁 等待
  • 可能在等待 flush 锁(在第六章讲过 flush tables with read lock 会加全局读锁)
    • 执行 flush statement 类语句可能发生锁等待,其中:
      • flush tables with read lock:会关闭所有打开的表并给所有的表在库层级添加一个全局的读锁
      • flush tables with read lock:不会被其他会话的事务阻塞。例如开启一个会话事务,更新,然后直接执行本会话 flush,此时再执行上一个会话事务的提交,提交由于 flush 进入了阻塞,在等待 flush 被unlock 之后,该事务的提交继续执行。(想要复现 flush tables with read lock 被阻塞的场景,可以让 select sleep(60) from t 来进行 —— 原理是持续不断地打开表对象)
      • flush table t with read lock:会首先获取 t 表的MDL写锁,因此它要首先等待所有打开 t 表的事务完成,然后才从表缓存中对表进行刷新,重新打开表,并获取表锁,随后将 MDL 写锁降级为 MDL 读锁。在获得表锁并进行 MDL 写锁降级后,其他连接可以读取该表,但不能更新表(DML、DDL)
      • flush table t with read lock:反而会被对应表的其他事务给阻塞到
  • 可能在等待行锁
    • 如果查询的语句加了读锁 —— lock in share mode,那当 读取的数据有写锁占用时,查询线程将被阻塞
      • lock in share mode:是要求当前读,也就是要读取最新的数据
      • 不加锁就是 一致性读,最开始读到什么,即使中间有人更新了,也读的是旧值

怎么排查查询语句很久没有反馈的情况 ? 讲一下你的步骤流程 ?

-- 查看当前库的所有线程
show processlist;
  • 此外,还可以通过 performance_schema 库 和 sys 库 来排查
show variables like '%performance_schema%';
set performance_schema = 'ON';
-- 开启此功能,会有10%的性能开销
  • 随后,执行
select * from performance_schema.setup_instruments where name='wait/lock/metadata/sql/mdl';
-- 若结果两者非YES,需设置YES,才可继续UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' where name='wait/lock/metadata/sql/mdl';
  • 那么,当出现查询线程被阻塞时,可以在其他会话执行
SELECT * from sys.schema_table_lock_waits;
SELECT blocking_pid from sys.schema_table_lock_waits;
  • 即可查出当前持有锁的线程

Untitled

  • 建议销毁线程时,执行 kill X 而非 kill query X
  • 因为当线程正在执行的语句非查询语句时,后者是无效的方法

数据量极少但查询很慢

什么情况下,数据量极少,但查询却很慢呢 ?

  • 热点更新语句,其在 MVCC 控制下,当前事务与最新数据版本间的回滚段过长时,查询会很慢
  • 一般直接加读锁(会进行当前读)进行验证当前数据与事务一致性视图下的数据差异
  • 例如下面这个语句:
select * from t where id=1select * from t where id=1 lock in share mode

Untitled

Untitled

这篇关于第十九章 为什么我只查一行的语句,也执行这么慢?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/566389

相关文章

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

python之流程控制语句match-case详解

《python之流程控制语句match-case详解》:本文主要介绍python之流程控制语句match-case使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录match-case 语法详解与实战一、基础值匹配(类似 switch-case)二、数据结构解构匹

grom设置全局日志实现执行并打印sql语句

《grom设置全局日志实现执行并打印sql语句》本文主要介绍了grom设置全局日志实现执行并打印sql语句,包括设置日志级别、实现自定义Logger接口以及如何使用GORM的默认logger,通过这些... 目录gorm中的自定义日志gorm中日志的其他操作日志级别Debug自定义 Loggergorm中的

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

在MySQL执行UPDATE语句时遇到的错误1175的解决方案

《在MySQL执行UPDATE语句时遇到的错误1175的解决方案》MySQL安全更新模式(SafeUpdateMode)限制了UPDATE和DELETE操作,要求使用WHERE子句时必须基于主键或索引... mysql 中遇到的 Error Code: 1175 是由于启用了 安全更新模式(Safe Upd

Spring Boot 整合 ShedLock 处理定时任务重复执行的问题小结

《SpringBoot整合ShedLock处理定时任务重复执行的问题小结》ShedLock是解决分布式系统中定时任务重复执行问题的Java库,通过在数据库中加锁,确保只有一个节点在指定时间执行... 目录前言什么是 ShedLock?ShedLock 的工作原理:定时任务重复执行China编程的问题使用 Shed

详解如何在React中执行条件渲染

《详解如何在React中执行条件渲染》在现代Web开发中,React作为一种流行的JavaScript库,为开发者提供了一种高效构建用户界面的方式,条件渲染是React中的一个关键概念,本文将深入探讨... 目录引言什么是条件渲染?基础示例使用逻辑与运算符(&&)使用条件语句列表中的条件渲染总结引言在现代

如何使用 Bash 脚本中的time命令来统计命令执行时间(中英双语)

《如何使用Bash脚本中的time命令来统计命令执行时间(中英双语)》本文介绍了如何在Bash脚本中使用`time`命令来测量命令执行时间,包括`real`、`user`和`sys`三个时间指标,... 使用 Bash 脚本中的 time 命令来统计命令执行时间在日常的开发和运维过程中,性能监控和优化是不

C#如何优雅地取消进程的执行之Cancellation详解

《C#如何优雅地取消进程的执行之Cancellation详解》本文介绍了.NET框架中的取消协作模型,包括CancellationToken的使用、取消请求的发送和接收、以及如何处理取消事件... 目录概述与取消线程相关的类型代码举例操作取消vs对象取消监听并响应取消请求轮询监听通过回调注册进行监听使用Wa