MySQL Sending data导致查询很慢的问题详细分析
这两天帮忙定位一个MySQL查询很慢的问题,定位过程综合各种方法、理论、工具,很有代表性,分享给大家作为新年礼物:)
【问题现象】
使用sphinx支持倒排索引,但sphinx从mysql查询源数据的时候,查询的记录数才几万条,但查询的速度非常慢,大概要4~5分钟左右
【处理过程】
1)explain
首先怀疑索引没有建好,于是使用explain查看查询计划,结果如下:
从explain的结果来看,整个语句的索引设计是没有问题的,除了第一个表因为业务需要进行整表扫描外,其它的表都是通过索引访问
2)show processlist;
explain看不出问题,那到底慢在哪里呢?
于是想到了使用 show processlist查看sql语句执行状态,查询结果如下:
发现很长一段时间,查询都处在 “Sending data”状态
查询一下“Sending data”状态的含义,原来这个状态的名称很具有误导性,所谓的“Sending data”并不是单纯的发送数据,而是包括“收集 + 发送 数据”。
这里的关键是为什么要收集数据,原因在于:mysql使用“索引”完成查询结束后,mysql得到了一堆的行id,如果有的列并不在索引中,mysql需要重新到“数据行”上将需要返回的数据读取出来返回个客户端。
3)show profile
为了进一步验证查询的时间分布,于是使用了show profile命令来查看详细的时间分布
首先打开配置:set profiling=on;
执行完查询后,使用show profiles查看query id;
使用show profile for query query_id查看详细信息;
结果如下:
从结果可以看出,Sending data的状态执行了216s
4)排查对比
经过以上步骤,已经确定查询慢是因为大量的时间耗费在了Sending data状态上,结合Sending data的定义,将目标聚焦在查询语句的返回列上面
经过一 一排查,最后定为到一个description的列上,这个列的设计为:`description`varchar(8000) DEFAULT NULL COMMENT '游戏描述',
于是采取了对比的方法,看看“不返回description的结果”如何。show profile的结果如下:
可以看出,不返回description的时候,查询时间只需要15s,返回的时候,需要216s,两者相差15倍
【原理研究】
至此问题已经明确,但原理上我们还需要继续探究。
这篇淘宝的文章很好的解释了相关原理:innodb使用大字段text,blob的一些优化建议
这里的关键信息是:当Innodb的存储格式是 ROW_FORMAT=COMPACT
(or ROW_FORMAT=REDUNDANT
)的时候,Innodb只会存储前768字节的长度,剩余的数据存放到“溢出页”中。
我们使用show table status来查看表的相关信息:
可以看到,平均一行大约1.5K,也就说大约1/10行会使用“溢出存储”,一旦采用了这种方式存储,返回数据的时候本来是顺序读取的数据,就变成了随机读取了,所以导致性能急剧下降。
另外,在测试过程中还发现,无论这条语句执行多少次,甚至将整个表select *几次,语句的执行速度都没有明显变化。这个表的数据和索引加起来才150M左右,而整个Innodb buffer pool有5G,缓存整张表绰绰有余,如果缓存了溢出页,性能应该大幅提高才对。
但实测结果却并没有提高,因此从这个测试可以推论Innodb并没有将溢出页(overflow page)缓存到内存里面。
这样的设计也是符合逻辑的,因为overflow page本来就是存放大数据的,如果也放在缓存里面,就会出现一次大数据列(blob、text、varchar)查询,可能就将所有的缓存都更新了,这样会导致其它普通的查询性能急剧下降。
【解决方法】
找到了问题的根本原因,解决方法也就不难了。有几种方法:
1)查询时去掉description的查询,但这受限于业务的实现,可能需要业务做较大调整
2)表结构优化,将descripion拆分到另外的表,这个改动较大,需要已有业务配合修改,且如果业务还是要继续查询这个description的信息,则优化后的性能也不会有很大提升。
转自:http://blog.csdn.net/yunhua_lee/article/details/8573621
MySQL Sending data导致查询很慢的问题详细分析的更多相关文章
- MySQL Sending data导致查询很慢的问题详细分析【转载】
转自http://blog.csdn.net/yunhua_lee/article/details/8573621 [问题现象] 使用sphinx支持倒排索引,但sphinx从mysql查询源数据的时 ...
- 实战:MySQL Sending data导致查询很慢的问题详细分析(转)
这两天帮忙定位一个MySQL查询很慢的问题,定位过程综合各种方法.理论.工具,很有代表性,分享给大家作为新年礼物:) [问题现象] 使用sphinx支持倒排索引,但sphinx从mysql查询源数据的 ...
- 实战:MySQL Sending data导致查询很慢的问题详细分析(转)
出处:http://blog.csdn.net/yunhua_lee/article/details/8573621 这两天帮忙定位一个MySQL查询很慢的问题,定位过程综合各种方法.理论.工具,很有 ...
- 0223实战:MySQL Sending data导致查询很慢的问题详细分析
转自博客http://blog.csdn.net/yunhua_lee/article/details/8573621 [问题现象] 使用sphinx支持倒排索引,但sphinx从mysql查询源数据 ...
- 1125MySQL Sending data导致查询很慢的问题详细分析
-- 问题1 tablename使用主键索引反而比idx_ref_id慢的原因EXPLAIN SELECT SQL_NO_CACHE COUNT(id) FROM dbname.tbname FORC ...
- MySQL编码不一致导致查询结果为空
升级数据库后(5.1到8.0),发现一个奇怪的问题,某些页面在升级前可以正常查询,但升级后什么也查不出来了,有时候还会查出错误的结果.经过一整天的排查,终于发现由两个原因导致,现记录如下. 第一是数据 ...
- in语句导致查询很慢
1.表A,表B,表C.其中A中的主键是B的外键,一对多的关系:B的主键是C的外键,一对多的关系.最终想查出所有符合条件的C. 原因:开发人员将A表数据先查出来,放到list中,然后用list作为in的 ...
- Mysql建了索引查询很慢
遇到一个问题,有几个结构一个的查询,表的索引建的也一样,但是有的查询很快,有的却很慢,需要半分钟以上才能执行完. 查看执行计划,并没有什么区别.找了很久原因才发现是主查询和子查询所涉及的表的字符编码不 ...
- MySQL字符集不一致导致查询SQL性能问题
今天做了一个MySQL数据库中的SQL优化. 结论是关联字段字符集不同,导致索引不可用. 查询的SQL如下: select `Alias`.`Grade`, `Alias`.`id`, `Alias` ...
随机推荐
- Java基础 - 变量的定义和使用
变量定义 public class Main { public static void main(String[] args) { // 定义byte类型的变量 byte b = 10; System ...
- [IOI2018]组合动作
IOI2018 组合动作 UOJ 首先显然可以两次试出首字母 考虑增量构造 假设首字母为A,且已经试出前i个字母得到的串s 我们考虑press这样一个串s+BB+s+BX+s+BY+s+XA 首先这个 ...
- $.ajax()方法详解(转)
转: http://www.cnblogs.com/tylerdonet/p/3520862.html 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: ...
- 从硬盘设计思想到RAID改良之道
监控硬盘的前生今世关于桌面硬盘.企业级近线硬盘(NL-SAS/SATA)和监控硬盘的差别,我们在前文中已经讲得很详细,这里再换一个角度来看看. "监控硬盘是希捷和西数为视频监控定制的,典型的 ...
- Java多线程系列 JUC线程池02 线程池原理解析(一)
转载 http://www.cnblogs.com/skywang12345/p/3509960.html ; http://www.cnblogs.com/skywang12345/p/35099 ...
- 【leetcode】Balanced Binary Tree
Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary ...
- Spark Structured Streaming框架(4)之窗口管理详解
1. 结构 1.1 概述 Structured Streaming组件滑动窗口功能由三个参数决定其功能:窗口时间.滑动步长和触发时间. 窗口时间:是指确定数据操作的长度: 滑动步长:是指窗口每次向前移 ...
- shell单例-处理方案
shell单例:当某一个shell脚本需要重复执行时(shell定时任务 etc),为了避免多个相同任务之间交叉,造成数据的混乱或者错误,需要脚本单例执行. 就是前一个进程执行时,后一个进程需要阻塞等 ...
- windows8.1下安装msi文件报错
新安装了win8.1系统体验体验,可是安装msi文件的软件报internal error2502和2503错误,可以换一种安装方式. 不是直接点开安装,如图所示打开命令提示符: 使用msiexec / ...
- RabbitMQ之Exchange
交换机的作用: 生产者发送消息不会向传统方式直接将消息投递到队列中,而是先将消息投递到交换机中,在由交换机转发到具体的队列,队列在将消息以推送或者拉取方式给消费者进行消费,这和我们之前学习Nginx有 ...