MySQL 19 为什么我只查一行的语句,也执行这么慢?
有些情况下,“查一行”也会执行特别慢,今天就看看什么情况会出现这个现象。
如果MySQL本身有很大压力,导致数据库服务器CPU占有率很高或IO利用率很高,这种情况所有语句的执行都可能变慢,不在本文讨论范围内。
为了分析,构建有10万行记录的表,建表语句如下:
CREATE TABLE `t` (
`id` int(11) NOT NULL,
`c` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
第一类:查询长时间不返回
比如执行语句:
select * from t where id=1;
查询结果长时间不返回:

一般碰到这种情况,大概率是表t被锁住。分析的时候,一般会先执行show processlist
命令,查看当前语句处于什么状态,然后再针对每种状态分析它们产生的原因、如何复现,以及如何处理。
等MDL锁
使用show processlist
命令示意图如下:

其中Waiting for table metadata lock状态表示,现在有一个线程正在表t上请求或者持有MDL写锁,将select语句堵住了。
比如有可能是如下的情况:

对于这种情况,可以通过查询sys.schema_table_lock_waits表,直接找出造成阻塞的process id,然后kill这个连接。

等flush
接下来看另外一种情况:

其中Waiting for table flush状态表示,现在有一个线程正要对表t做flush操作。MySQL里对表做flush操作的用法,一般有以下两个:
flush tables t with read lock;
flush tables with read lock;
如果指定表t,代表只关闭表t;如果没有指定具体的表名,则表示关闭MySQL里所有打开的表。
正常情况下,这两个语句执行起来都很快,除非它们也被别的线程堵住了。
所以出现Waiting for table flush状态的可能情况是:有一个flush tables命令被别的语句堵住了,然后它又堵住了select语句。可能的情况如下:

在session A中,每行都调用一次sleep(1),这样对于10万行的表,该语句默认执行10万秒,在这期间表t一直被session A“打开”着。然后,session B想要关闭表t就需要等session A查询结束,而session C会被flush命令堵住。
可以用show processlist
查看process状态,然后手动kill相关process。

等行锁
由于访问id=1
记录时要加读锁,如果这时候已经有一个事务在这行记录上持有一个写锁,select语句就会被堵住:

session A启动了事务,占有写锁还不提交,导致session B被堵住。
可以通过sys.innodb_lock_waits表查看是谁占着写锁:
select * from t sys.innodb_lock_waits where locked_table='`test`.`t`'\G

可以看到4号线程造成了堵塞,因此需要kill 4
断开连接。当连接被断开,会自动回滚该连接里正在执行的流程,也就会释放id=1
上的行锁。
第二类:查询慢
看一个只扫描一行,但执行很慢的语句:
select * from t where id=1;
其slow log如下:

可以发现,虽然扫描行数是1,但执行时间却长达800ms。
继续看slow log下面的内容,是下一个语句,扫描行数1行,执行时间为0.2ms:

看起来有些奇怪,毕竟lock in share mode还要加锁,按理说时间会更长。
查看这两个语句的执行输出结果:

第一个语句查询结果c=1
,第二个语句查询结果c=1000001
,所以里面有对c字段的改变,实际上对应下面这种情况:

session A先启动了事务,然后session B开始执行update语句。更新完成后,id=1
对应的状态如下:

session B更新完,生成了100万个回滚日志。
第二个查询语句是当前读,会直接读到1000001这个结果,所以速度很快;而第一个查询语句是一致性读,需要回滚100万次得到1这个结果,因此速度很慢。
undo log里记录的其实是“把 2 改成 1”,“把 3 改成 2”这样的操作逻辑,画成减1是方便看图。
MySQL 19 为什么我只查一行的语句,也执行这么慢?的更多相关文章
- MySQL 笔记整理(19) --为什么我只查一行的语句,也执行这么慢?
笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 19) --为什么我只查一行的语句,也执行这么慢? 需要说明一下,如果M ...
- 《Mysql - 为什么只查一行的数据,也这么慢?》
概念 - 在某些情况下,“查一行”,也会执行得特别慢. - 下面分析在什么情况下,会出现这个现象. - 基础工作(构建数据库环境) - 建立 t 表,并写入 10W 的数据. CREATE TABLE ...
- mysql基本的增删改查和条件语句
增 insert into 表名(列名,列名......) values("test1",23),("test2",23),("test3" ...
- mysql之workbench如何只导出(insert语句)数据
https://www.jianshu.com/p/a5cd14bc5499 1. 说明: 出发点: 由于特殊原因,我们只想导出数据库中的数据(insert into语句格式的),但是在网上找到的资源 ...
- 转!mysql 命令行下 通过DELIMITER临时改变语句分隔符 执行存储过程
mysql 在 Navicat 界面工具 执行存储过程ok,但是在命令行下执行失败. 原因在于,默认的MySQL语句分隔符为' ; ',在输入' ; '的时候,“以为”语句已经结束了,但实际上语句还没 ...
- Mysql,重复字段只取其中一行
Mysql,重复字段只取其中一行 格式 : select 字段 from [表] where 其他字段 in (select 函数(其他字段) from [表] group by 相同字段) 示例如下 ...
- java jdbc 连接mysql数据库 实现增删改查
好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打 ...
- 新手MySQL工程师必备命令速查手册
MySQL的基本操作可以包括两个方面:MySQL常用语句如高频率使用的增删改查(CRUD)语句和MySQL高级功能,如存储过程.触发器.事务处理等.而这两个方面又可以细分如下: 1.MySQL常用语句 ...
- sed 's/AA/BB/' file # 将文件中的AA替换成BB,只替换一行中第一次出现的AA,替换后的结果输出到屏幕 sed 's/AA/BB/g' file # 将文件中的所有AA都替换成BB,替换后的结果输出到屏幕
生信人的自我修养:Linux命令速查手册 简佐义 四川大学 生物信息学硕士 科学求真 赢 10 万奖金 · 院士面对面 209 人赞同了该文章 许多人做生物信息学,要么不重视Linux,要么不知道 ...
- 【JavaEE】Hibernate继承映射,不用多态查询只查父表的方法
几个月前,我在博问里面发了一个问题:http://q.cnblogs.com/q/64900/,但是一直没有找到好的答案,关闭问题以后才自己解决了,在这里分享一下. 首先我重复一下场景,博问里面举的动 ...
随机推荐
- 【笔记】Excel 2021|VBA删除数组中的一个元素、循环时删除一行、选择一列删除指定一行
主要问题是循环的时候删除一行比较麻烦,因为删除了一行后,循环仍然直接访问后一行,会导致一定的异常. 文章目录 选择一列,删除指定一行 删除数组中的一个元素 方法1:利用动态数组,在循环中条件判断删除 ...
- 阻塞式IO
无法被打断的进程 在进行阻塞IO实验的时候,发现后台运行了/imx6uirqAPP /dev/imx6uirq &之后无法用kill -9 xxx杀死后台进程. 只需要将驱动中的 wait_e ...
- TGCTF-misc全解
TGCTF-misc方向wp next is the end 下载压缩包,拉出第一层文件夹,直接嵌套读取内容找flag import os def is_last_level_dir(director ...
- Windows平台调试器原理与编写01.调试框架
调试器原理与编写01.调试框架-C/C++基础-断点社区-专业的老牌游戏安全技术交流社区 - BpSend.net 调试框架 调试器最基本功能: 断点,单步 断点分为三类 软件断点 硬件断点 内存断点 ...
- odoo16里面修改tree视图样式
一.在static文件夹下新建一个css文件夹并将*.css文件写入 /*该文件用来定义视图中的一些格式,需要用到的地方直接在xml文件中进行引用*/ /*语法说明*/ /* table th:nth ...
- 「Log」做题记录 2024.1.1-2024.1.28
\(2024.1.1-2024.1.7\) \(\color{blueviolet}{P1501}\) LCT 板子,链加链乘查询链和,断边加边. \(\color{black}{P4332}\) L ...
- 如何使用MCP开发一个客户端和服务端
如何使用MCP开发一个客户端和服务端 一.MCP和API以及Function Call核心概念对比 特性 API Function Call MCP (Model Context Protocol) ...
- 【中文】【吴恩达课后编程作业】Course 1 - 神经网络和深度学习 - 第二周作业
[吴恩达课后编程作业]Course 1 - 神经网络和深度学习 - 第二周作业 - 具有神经网络思维的Logistic回归 上一篇:[课程1 - 第二周测验]※※※※※ [回到目录]※※※※※下一篇: ...
- kubernetes配置glusterfs动态存储
GlusterFS分布式文件系统 一.简单介绍 分布式存储按其存储接口分为三种:文件存储.块存储.对象存储 文件存储 通常支持POSIX接口(如glusterFS,但GFS.HDFS是非POSIX接口 ...
- 爆肝整理!0 基础 AI 编程必拿的 3 大神器:源码一键跑 + 推广秘籍 + 私教答疑
2025年预期的 AI 应用爆发并没有到来,但是编程领域却是个特例.AI 编程工具正在引领大模型落地的浪潮,展现出明显的产品市场契合度(Product Market Fit,PMF). 那么在全面智能 ...