当前位置: 首页 > news >正文

MySQL查询执行(四):查一行也很慢

假设存在表t,这个表有两个字段id和c,并且我在里面插入了10万行记录。

-- 创建表t
CREATE TABLE `t` (`id` int(11) NOT NULL,`c` int(11) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB;-- 通过存储过程向t写入10w行数据
delimiter ;;
create procedure idata()
begindeclare i int;set i=1;while(i<=100000)doinsert into t values(i,i);set i=i+1;end while;
end;;
delimiter ;-- 插入数据
call idata();

查询长时间不返回


查询长时间不返回的原因:被其他线程堵住了。

在表t执行下面的SQL语句:

select * from t where id = 1;

查询结果长时间不返回。

一般碰到这种情况的话, 大概率是表t被锁住了。 接下来分析原因的时候, 一般都是首先执行一下show processlist命令, 看看当前语句处于什么状态。

然后我们再针对每种状态, 去分析它们产生的原因、 如何复现, 以及如何处理。

场景一:等MDL锁

如图所示, 就是使用show processlist命令查看Waiting for table metadata lock的示意图。

出现这个状态表示的是, 现在有一个线程正在表t上请求或者持有MDL写锁, 把select语句堵住了。

在MySQL 5.7版本下复现这个场景, 如图所示, 我给出了简单的复现步骤。

session A 通过lock table命令持有表t的MDL写锁, 而session B的查询需要获取MDL读锁。 所以, session B进入等待状态。

这类问题的处理方式, 就是找到谁持有MDL写锁, 然后把它kill掉。

问:如何找到是谁持有MDL写锁呢?

方式一:如果session A在加表锁后,接着执行了别的语句,那么便可通过执行show processlist命令找到造成阻塞的process id。

方式二:如果如果session A在加表锁后,没有执行任何命令,即Command列是“Sleep”。此时需要通过查询sys.schema_table_lock_waits这张表,找出造成阻塞的process id。(MySQL启动时需要设置performance_schema=on,MySQL5.5默认是关闭此功能的,若要开启,需手动在配置文件里添加,从MySQL5.6开始,默认打开此功能)

在上述场景下,另启一个session C,然后执行:

select blocking_pid from sys.schema_table_lock_waits;

执行结果:

最后,在找到造成阻塞的process id后,把这个连接用kill命令断开即可。

场景二:等flush

MySQL里面对表做flush操作的用法, 一般有以下两个:

-- flush指定table
flush tables t with read lock;--flush全部table 
flush tables with read lock;

这两个flush语句, 如果指定表t的话, 代表的是只关闭表t; 如果没有指定具体的表名, 则表示关闭MySQL里所有打开的表。

正常情况下,这两个语句执行起来都很快, 除非它们也被别的线程堵住了。

所以, 出现Waiting for table flush状态的可能情况是: 有一个flush tables命令被别的语句堵住了, 然后它又堵住了我们的select语句。

注:flush table的作用,关闭表,并清空查询缓存。

现在, 我们一起来复现一下这种情况, 复现步骤如图所示:

在session A中, 我故意每行都调用一次sleep(1), 这样这个语句默认要执行10万秒, 在这期间表t一直是被session A“打开”着。 然后, session B的flush tables t命令再要去关闭表t, 就需要等session A的查询结束。 这样, session C要再次查询的话, 就会被flush 命令堵住了。

这个复现步骤的show processlist结果:

看到这个show processlist的结果, 肯定就知道应该怎么做了。

场景三:等行锁

经过了表级锁的考验, 我们的select 语句终于来到引擎里了。

select * from t where id=1 lock in share mode;

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

复现步骤和现场如下:

显然, session A启动了事务, 占有写锁, 还不提交, 是导致session B被堵住的原因。

问:等行锁的场景下,怎么查出是谁占着这个写锁呢?

答:如果是MySQL5.7及以上版本,可以通过sys.innodb_lock_waits 表查到。

查询方法:

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

执行结果:

可以看到, 这个信息很全, 4号线程是造成堵塞的罪魁祸首。 而干掉这个罪魁祸首的方式, 就是KILL 4。

查询慢


经过了重重封“锁”, 我们再来看看一些查询慢的例子。

先来看一条你一定知道原因的SQL语句:

select * from t where c = 50000 limit 1;

由于字段c上没有索引, 这个语句只能走id主键顺序扫描, 因此需要扫描5万行。

接下来, 我们再看一个只扫描一行, 但是执行很慢的语句。

select * from t where id = 1;

慢查询结果:

虽然扫描行数是1, 但执行时间却长达800毫秒。是不是有点奇怪呢, 这些时间都花在哪里了?

如果我把这个slow log的截图再往下拉一点, 你可以看到下一个语句, select * from t where id=1 lock in share mode, 执行时扫描行数也是1行, 执行时间是0.2毫秒。

看上去是不是更奇怪了? 按理说lock in share mode还要加锁, 时间应该更长才对啊。

场景复现:

session A先用start transaction with consistent snapshot(该命令启动事务时就创建了一致性视图)命令启动了一个事务, 之后session B才开始执行update 语句。session B更新完100万次, 生成了100万个回滚日志(undo log)。

session A在执行select * from t where id=1时,需要判断当前记录的可见性,由于session B执行了100万次,所以session A需要判断100万次,这也就是为什么select * from t where id=1语句执行的比较慢。

session A在执行select * from t where id=1 lock in share mode时,直接读最新记录即可,无需判断记录的可见性,所以执行的比较快。

上述两个语句的执行输出结果:

 假设有如下表结构:

CREATE TABLE `t`(`id` int(11) NOT NULL,`c` int(11) DEFAULT NULL,`d` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY c (`c`)
) ENGINE=InnoDB;insert into t values(0,0,0),(5,5,5),(10,10,10),(15,15,15),(20,20,20),(25,25,25);

小结:思考题


思考:如果执行如下语句,语句序列是怎么加锁的?锁又是什么时候释放的?

begin;
select * from t where c = 5 for update;
commit;

 这个语句会命中d=5的这一行, 对应的主键id=5, 因此在select 语句执行完成后, id=5这一行会加一个写锁, 而且由于两阶段锁协议, 这个写锁会在执行commit语句的时候释放。

相关文章:

MySQL查询执行(四):查一行也很慢

假设存在表t&#xff0c;这个表有两个字段id和c&#xff0c;并且我在里面插入了10万行记录。 -- 创建表t CREATE TABLE t (id int(11) NOT NULL,c int(11) DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB;-- 通过存储过程向t写入10w行数据 delimiter ;; create procedure idat…...

【Obsidian】当笔记接入AI,Copilot插件推荐

当笔记接入AI&#xff0c;Copilot插件推荐 自己的知识库笔记如果增加AI功能会怎样&#xff1f;AI的回答完全基于你自己的知识库余料&#xff0c;是不是很有趣。在插件库中有Copilot插件这款插件&#xff0c;可以实现这个梦想。 一、什么是Copilot&#xff1f; 我们知道githu…...

Spring Cloud集成Gateaway

Spring Cloud Gateway 是一个基于 Spring 生态的网关框架&#xff0c;用于构建微服务架构中的API网关。它可以对请求进行路由、过滤、限流等操作&#xff0c;是Spring Cloud微服务体系中常用的组件之一。下面介绍 Spring Cloud Gateway 的核心概念、应用场景以及简单的示例。 …...

如何准备技术面试?

大家好&#xff0c;我是老三&#xff0c;好久没更新了&#xff0c;翻出之前的一篇旧稿&#xff0c;是一篇总纲性质的文章——如何准备一场技术面试。这篇文章原本的开头是写给金三银四的&#xff0c;转眼就“金九银十”了&#xff0c;每一年都是最差的一年&#xff0c;又是未来…...

Kafka原理剖析之「Topic创建」

一、前言 Kafka提供了高性能的读写&#xff0c;而这些读写操作均是操作在Topic上的&#xff0c;Topic的创建就尤为关键&#xff0c;其中涉及分区分配策略、状态流转等&#xff0c;而Topic的新建语句非常简单 bash kafka-topics.sh \ --bootstrap-server localhost:9092 \ // …...

Java 高级学习路线概要~

前言&#xff1a;恭喜你已经掌握了 Java 的基础知识&#xff01;现在&#xff0c;让我们踏上 Java 高级学习之旅&#xff0c;探索更强大的编程技巧和技术。学习前记得不要忘了巩固和加强基础的学习哦&#xff0c;高级学习也是建立在基础的学习之上。 1. 集合框架进阶 Map 接口…...

浏览器插件快速开启/关闭IDM接管下载

假设你已经为浏览器安装了IDM扩展&#xff0c;那么按下图的点击顺序&#xff0c;可以快速开启或关闭IDM的下载接管&#xff0c;而不必在IDM软件的设置->选项中&#xff0c;临时作调整。...

初识c++:入门基础

打字不易&#xff0c;留个赞再走吧~~ 目录 一.第一个c程序二.命名空间 namespace三.C输⼊&输出四.缺省参数 C兼容C语⾔绝⼤多数的语法&#xff0c;所以C语⾔实现的hello world依旧可以运⾏&#xff0c;C中需要把定义⽂件 代码后缀改为.cpp 一.第一个c程序 做好准备我们来写…...

Java Exception 异常相关总结

1.简介 在Java中&#xff0c;当代码运行有问题时会抛出异常&#xff0c;主要分为两类&#xff1a; 1.可以通过try...catch来捕获解决的&#xff0c;不影响后续执行的RuntimeException。 2.不可以通过代码解决的Exception。 为了提高代码的健壮性&#xff0c;我们会选择去捕…...

HighCharts图表自动化简介

什么是分析数据? 在任何应用程序中捕获并以图形或图表形式显示的分析数据是任何产品或系统的关键部分,因为它提供了对实时数据的洞察。 验证此类分析数据非常重要,因为不准确的数据可能会在报告中产生问题,并可能影响应用程序/系统的其他相关领域。 什么是HighChart? …...

使用LDAP登录GitLab

使用LDAP登录GitLab gitlab.rb 配置如下 gitlab_rails[ldap_enabled] true #gitlab_rails[prevent_ldap_sign_in] false###! **remember to close this block with EOS below** gitlab_rails[ldap_servers] YAML.load <<-EOSmain:label: LDAPhost: 172.16.10.180port:…...

【2024】前端学习笔记5-表单标签使用

表单是网页提供的一种交互式操作手段,主要用于采集用户输入的信息。 学习笔记 1.表单框架:form标签1.1.action属性:目标指向1.2.method属性:提交方式1.3.id属性:唯一标识1.4.placeholder属性:提示文字2.input标签2.1.text类型:基本文本输入2.2.password类型:密码输入2.…...

数据结构--二叉树(C语言实现,超详细!!!)

文章目录 二叉树的概念代码实现二叉树的定义创建一棵树并初始化组装二叉树前序遍历中序遍历后序遍历计算树的结点个数求二叉树第K层的结点个数求二叉树高度查找X所在的结点查找指定节点在不在完整代码 二叉树的概念 二叉树&#xff08;Binary Tree&#xff09;是数据结构中一种…...

【将字符串变为空的编辑距离】

题目描述 求由s串变成t串的编辑距离 在s串的开头/末尾添加一个字符&#xff0c;花费p 在s串的开头/末尾添加一个s串的子串&#xff0c;花费q 每次作都是基于当前的s串 s串初始为空 分析 等价于将一个字符串变为空串的过程 第一层按照长度遍历&#xff08;如果按照下标i,j遍…...

卡特兰数的推理

卡特兰数&#xff08;Catalan number&#xff09;&#xff0c;又称卡塔兰数、明安图数&#xff0c;是组合数学中一种常出现于各种计数问题中的数列。它以比利时数学家欧仁查理卡特兰的名字命名&#xff0c;但值得注意的是&#xff0c;这一数列的首次发现可以追溯到1730年&#…...

高精度治具加工的重要性和优势

在现代工业制造中&#xff0c;高精度治具加工扮演着举足轻重的角色。它不仅关乎产品制造的精度与质量&#xff0c;还直接影响到生产效率和成本控制。因此&#xff0c;时利和将深入探讨高精度治具加工的重要性和优势&#xff0c;对于提升工业制造水平具有重要意义。 高精度治具加…...

新版IDEA提示@Autowired不建议字段注入

随着项目的复杂度的增加&#xff0c;我们通常会在一个业务类中注入其他过多的业务类。从而使当前的业务层扩充成一个大而全的功能模块。那么就容易出现一下问题 字段注入会让依赖关系变得不那么明显&#xff0c;因为你无法通过构造函数看到所有的依赖项。使用构造函数时&#…...

adb的安装和使用 以及安装Frida 16.0.10+雷电模拟器

.NET兼职社区 .NET兼职社区 .NET兼职社区 1.下载adb Windows版本&#xff1a;https://dl.google.com/android/repository/platform-tools-latest-windows.zip 2.配置adb环境变量 按键windowsr打开运行&#xff0c;输入sysdm.cpl&#xff0c;回车。 高级》环境变量》系统变量》…...

解决移动端1px 边框优化的8个方法

前言 您是否注意到 1px 边框在移动设备上有时会显得比预期的要粗&#xff1f;这种不一致源于移动屏幕的像素密度不同。 在 Web 开发中&#xff0c;我们使用 CSS 来设置页面样式。但是&#xff0c;CSS 中的 1px 并不总是转换为设备上的物理 1px。这种差异就是我们的“1px 边框…...

频带宽度固定,如何突破数据速率的瓶颈?

目录 目录 引言 信道 频带宽度 信噪比 信噪比的重要性 影响信噪比的因素 码元 码元的特点&#xff1a; 码元与比特的关系&#xff1a; 码元的作用&#xff1a; 码元的类型&#xff1a; Question 类比解释&#xff1a; 技术解释&#xff1a; 引言 在现代通信系统中…...

macOS沙盒限制下运行OpenClaw:ollama-QwQ-32B权限解决方案

macOS沙盒限制下运行OpenClaw&#xff1a;ollama-QwQ-32B权限解决方案 1. 问题背景&#xff1a;当自动化遇上macOS沙盒 上周我尝试在macOS Ventura上部署OpenClaw对接本地ollama-QwQ-32B模型时&#xff0c;遭遇了典型的"权限墙"——明明所有服务都正常运行&#xf…...

文墨共鸣大模型安装包依赖分析与环境冲突解决

文墨共鸣大模型安装包依赖分析与环境冲突解决 你是不是也遇到过这种情况&#xff1a;拿到一个项目&#xff0c;兴冲冲地运行 pip install -r requirements.txt&#xff0c;结果屏幕上开始疯狂报错&#xff0c;各种版本不兼容、找不到模块、编译失败的信息轮番轰炸。折腾了几个…...

AI超清画质增强镜像使用技巧:避免移动端适配的3个坑

AI超清画质增强镜像使用技巧&#xff1a;避免移动端适配的3个坑 1. 理解镜像的核心能力与限制 在移动端使用AI超清画质增强镜像前&#xff0c;必须清楚了解它能做什么、不能做什么。这个基于OpenCV EDSR模型的镜像&#xff0c;本质上是一个专注图像重建的轻量级服务。 1.1 核…...

CPython 3.12+新特性深度适配:细粒度GIL释放、Per-Interpreter GIL与扩展模块线程模型重构指南

第一章&#xff1a;CPython 3.12扩展模块开发范式演进总览CPython 3.12 标志着 C 扩展开发进入“安全优先、API 稳定、工具链现代化”的新阶段。官方正式弃用长期存在的 PyEval_InitThreads() 和隐式 GIL 管理惯用法&#xff0c;同时强化了 PyModuleDef 初始化语义与跨版本 ABI…...

ECharts甘特图实战:5分钟搞定项目进度可视化(附完整代码)

ECharts甘特图实战&#xff1a;5分钟搞定项目进度可视化&#xff08;附完整代码&#xff09; 项目管理中&#xff0c;进度可视化是团队协作的核心需求。传统表格难以直观展示任务依赖关系&#xff0c;而专业项目管理软件又过于笨重。ECharts作为国内最流行的数据可视化库&…...

如何在Windows上实现高效完整的安卓应用安装:APK-Installer进阶指南

如何在Windows上实现高效完整的安卓应用安装&#xff1a;APK-Installer进阶指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer APK-Installer是一款专为Windows系统设…...

QWen 3.5plus总结的总结基准测试结果的正确方法

原文地址&#xff1a;https://dl.acm.org/doi/epdf/10.1145/5666.5673 如何用统计撒谎&#xff1a;总结基准测试结果的正确方法 作者&#xff1a;PHILIP J. FLEMING 和 JOHN J. WALLACE 在文献中&#xff0c;性能结果经常使用性能比率的算术平均值来总结&#xff0c;在某些情况…...

科研人投稿破局:Paperxie AI 期刊写作,把「拒稿重写」变成「一次过审」

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/期刊论文https://www.paperxie.cn/ai/journalArticleshttps://www.paperxie.cn/ai/journalArticles 在学术圈&#xff0c;「写期刊论文」从来都不是敲字那么简单 —— 要贴合期刊收稿方向、要挖创新点、要卡…...

大模型小白程序员必看:收藏这份AI智能体学习路径与构建思路

大模型小白程序员必看&#xff1a;收藏这份AI智能体学习路径与构建思路 本文系统梳理AI智能体的概念、发展脉络与核心架构&#xff0c;清晰拆解其与传统工作流的本质差异&#xff0c;聚焦智能体三大核心组件&#xff08;规划能力、记忆系统、工具使用机制&#xff09;的技术细节…...

硬件设计避坑指南:为什么你的AD原理图转PCB总会丢失元器件位号?

硬件工程师必看&#xff1a;AD原理图转PCB丢失元器件位号的深度解析与根治方案 每次打开Altium Designer准备将精心设计的原理图导入PCB时&#xff0c;却发现所有元器件位号神秘消失——这种场景对硬件工程师来说简直是一场噩梦。位号不仅是元器件在PCB上的身份标识&#xff0c…...