查询数据不多,但却很慢的原因

这篇文章主要记录,造成查询数量不大的情况下,造成查询缓慢的原因,以及相应的解决方法。

环境说明:

  1. MySQL 版本 5.7.27
  2. 隔离级别:RR

锁等待造成查询速度很慢

MDL 锁

如开启如下事务:

Session A Session B
lock table t write;
begin;
select * from t where id=1;

Session A 持有表 t MDL 写锁。Session B 需要 MDL 读锁。这时读写锁互斥,Session B 被阻塞。

flush 阻塞

flush 操作一般来说很快就能执行完,当通过查询进程状态后,看到被 flush 操作被阻塞,一般都是由其他语句引起的。

如下面事务:

Session A Session B Session C
select sleep(1) from t;
flush tables t;
select * from t where id =1;

Session A 在扫描每一行时会休眠1s,而 Session B 的 flush tables t; 需要关闭表 t,要等 Session A 结束。后面的 Session C 被 Session B 阻塞了。

flush 的操作示范:

#  flush 表 t
flush tables t with read lock;
# flush 所有表
flush tables with read lock;

flush 的作用在 全局锁 文章中已经介绍过,FTWRL 主要用于 MyISAM 这样不支持事务的引擎,保证在备份时视图数据一致性。

行锁

这里的行锁,用两阶段锁来体现。其他如间歇锁和 next-key 锁都会可以造成这样的现象。

Session A Session B
begin;
update t set c=c+1 where id=1 select * from t where id=1 lock in share mode;

Session A 拥有 id=1 这行的写锁,Session B 想要拥有这一行的读锁,读写锁互斥。

解决方法

首先通过 show processlist; 命令查询被阻塞的状态信息。如需进一步分析的话,可以将 performance_schema=on 打开,通过查询 select blocking_pid from sys.schema_table_lock_waits; 具体造成锁等待的原因。然后 kill掉相应的 session.

在打开 performance_schema 会有一定的性能损失。

查询确实慢

没有设置合适的索引

如果没有设置合适的索引,导致扫描行数过多,时间自然就慢了。对于这种情况,可以开启慢查询日志,查看语句的执行过程,然后进行分析。

默认情况,慢查询日志时关闭的,打开方式如下:

# 查询慢查询日志状态及存储位置
# show variables  like '%slow_query_log%';

# 查询慢查询日志的设置时间
show variables  like '%long_query%';

# 临时打开慢查询日志,MySQL 重启后失效
set global slow_query_log=1;

# 改变时间
set long_query_time=0;

事务隔离的影响

事务究竟有没有被隔离这篇中,我们知道表中的每行数据都有多个版本,在一致性视图开启后,视图的一致性读的结果就是通过和数据行的版本比较进而显示的结果。

Session A Session B
start transaction with consistent snapshot;
update t set c=c+1 where id=1
update set c=c+1 where id=1; // 100 万次
select * from t where id=1;
select * from t where id=1 lock in share mode;

这时第一个 select 语句就会比第二个加锁的 select 语句还要慢。

因为第一个 select 语句是一致性读,需要从 100 万条回滚日志中比较直到找到适合的版本。

而第二个 select 语句是当前读,直接读取最新版本就可以了。所以花费的时间不一样。

总结

造成查询小数据量,却很缓慢的原因一般有两种,第一种可能是所查数据被锁住。另一种确实是查找过程是真的很慢。

对于数据被锁住的情况,一般会由 MDL 锁,FLUSH 操作被阻塞,行锁造成。

对于查询确实很慢来说,考虑下索引是否设置的合适。并注意在 RR 级别下,是否由于一致性读和当前读的不同而造成查询速度不一致的情况。

在分析原因时,可以通过进程状态以及 sys.innodb_lock_waits 中的信息,来做出相应的处理。

参考

https://dev.mysql.com/doc/refman/5.7/en/flush.html

https://dev.mysql.com/doc/internals/en/flush-tables.html

原文地址:https://www.cnblogs.com/michael9/p/12330392.html

时间: 2024-11-16 18:47:02

查询数据不多,但却很慢的原因的相关文章

MySQL入门很简单: 8查询数据

1. 查询语句语法 SELECT 属性列表 FROM 表名和视图列表 [WHERE 条件表达式1] [GROUP BY 属性名1 [HAVING t条件表达式2]] [ORDER BY 属性名2 [ASC| DESC] ] 2. 在单表上查询数据 1)查询所有字段 第一种方法:列出表的所有字段 SELECT num, name, age, sex FROM employee; 第二种方法:使用*查询所有字段 SELECT * FROM 表名 2)查询指定字段 //结果字段与SELECT语句中字段

用struts2标签如何从数据库获取数据并在查询页面显示。最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变量。

最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变量.<s:iterator>标签有一个value属性,用来存放在Action类的方法中存数据的list集合,还有一个id,好像是说指定集合的索引的意思,就是给list集合遍历出来的每个对象加上一个数字标签,反正我是这么理解的,没用过.还有一个很重要,就是var变量,我在s:iterator按ctr

QGrid系列教程--查询数据、编辑数据、删除数据

查询数据 在ProcessRequest 函数下修改: public void ProcessRequest(HttpContext context) { //查找 if (context.Request.Params.Get("_search") == "true") { return; } NameValueCollection forms = context.Request.Form; string strOperation = forms.Get("

sqlite学习笔记5:插入数据,查询数据和删除数据

曾闻:全部的编程都是已数据为中心,觉得很有道理. 所谓数据库数据库,没有数据叫什么数据库,接下来就看看怎样在表中插入数据. 一 插入数据 1 创建一张表 首先为了插入数据,须要先创建一张表: CREATE TABLE COMPANY( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL ); 2 第一种方式:指定列 插入数据有两种主要的格式,第一种是指定列

初学MongoDB实践笔记——安装、创建数据库、保存及查询数据

MongoDB是一个可扩展.高性能的分布式文档存储数据库,由C 语言编写,旨在为web应用提供可扩展的高性能数据存储解决方案.它的特点是高性能.易部署.易使用,存储数据非常方便. Mongo DB 是目前在IT行业非常流行的一种非关系型数据库(NoSql),其灵活的数据存储方式备受当前IT从业人员的青睐.Mongo DB很好的实现了面向对象的思想(OO思想),在Mongo DB中每一条记录都是一个Document对象.Mongo DB最大的优势在于所有的数据持久操作都无需开发人员手动编写SQL语

查询数据

查询数据指从数据库中获取所需要的数据.查询数据是数据库操作中最常用,也是最重要操作.用户可能根据自己对数据的需求,使用不同的查询方式.通过不同的查询方式,可以获得不同的数据.MySQL中是使用SELECT语句来查询数据的. - 查询语句的基本语法 - 在单表上查询数据 - 使用聚合函数查询数据 - 多表上联合查询 - 子查询 - 合并查询结果 - 为表和字段取别名 - 使用正则表达式查询 10.1 基本查询语句 查询数据是数据库操作中最常用的操作.通过对数据库的查询,用户可以从数据库中获取需要的

查询在应用程序运行得很慢, 但在SSMS运行得很快的原因探究

原文:查询在应用程序运行得很慢, 但在SSMS运行得很快的原因探究 查询在应用程序运行得很慢, 但在SSMS运行得很快的原因探究 -理解性能疑点 1      引言 内容来自http://www.sommarskog.se/query-plan-mysteries.html(Slow in the Application, Fast in SSMS?) [看国内没有人好好翻译过这篇.全部翻译实在太长了,就挑主要的意译了.如果要看完整版,还是建议读原文.先翻译了一半,先解决了眼前的问题.剩下的一般

答:SQLServer DBA 三十问之一: char、varchar、nvarchar之间的区别(包括用途和空间占用);xml类型查找某个节点的数据有哪些方法,哪个效率高;使用存储 过程和使用T-SQL查询数据有啥不一样;

http://www.cnblogs.com/fygh/archive/2011/10/18/2216166.html 1. char.varchar.nvarchar之间的区别(包括用途和空间占用):xml类型查找某个节点的数据有哪些方法,哪个效率高:使用存储 过程和使用T-SQL查询数据有啥不一样: ------------------------------------------------ SQL中char.varchar.nchar.nvarchar的区别 http://www.cn

Web jquery表格组件 JQGrid 的使用 - 7.查询数据、编辑数据、删除数据

系列索引 Web jquery表格组件 JQGrid 的使用 - 从入门到精通 开篇及索引 Web jquery表格组件 JQGrid 的使用 - 4.JQGrid参数.ColModel API.事件及方法 Web jquery表格组件 JQGrid 的使用 - 5.Pager翻页.搜索.格式化.自定义按钮 Web jquery表格组件 JQGrid 的使用 - 6.准备工作 & Hello JQGrid Web jquery表格组件 JQGrid 的使用 - 7.查询数据.编辑数据.删除数据