实战:MySQL Sending data导致查询很慢的问题详细分析(转)
这两天帮忙定位一个MySQL查询很慢的问题,定位过程综合各种方法、理论、工具,很有代表性,分享给大家作为新年礼物:)
【问题现象】
使用sphinx支持倒排索引,但sphinx从mysql查询源数据的时候,查询的记录数才几万条,但查询的速度非常慢,大概要4~5分钟左右
【处理过程】
1)explain
首先怀疑索引没有建好,于是使用explain查看查询计划,结果如下:

从explain的结果来看,整个语句的索引设计是没有问题的,除了第一个表因为业务需要进行整表扫描外,其它的表都是通过索引访问
2)show processlist;
explain看不出问题,那到底慢在哪里呢?
于是想到了使用 show processlist查看sql语句执行状态,查询结果如下:

从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的信息,则优化后的性能也不会有很大提升。
实战:MySQL Sending data导致查询很慢的问题详细分析(转)的更多相关文章
- 实战: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查询源数据 ...
- MySQL Sending data导致查询很慢的问题详细分析【转载】
转自http://blog.csdn.net/yunhua_lee/article/details/8573621 [问题现象] 使用sphinx支持倒排索引,但sphinx从mysql查询源数据的时 ...
- MySQL Sending data导致查询很慢的问题详细分析
这两天帮忙定位一个MySQL查询很慢的问题,定位过程综合各种方法.理论.工具,很有代表性,分享给大家作为新年礼物:) [问题现象] 使用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` ...
随机推荐
- 【LeetCode】Path Sum II 二叉树递归
Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given su ...
- PS-点击选中某一个图层
需要点击选中某一图层的时候,需要勾选[自动选择]
- 学习技巧-如何在IBM官网寻找学习资料
场景:最近看招聘职位TM1比较火,于是就想找一下Cognos TM1的资料来拜读一下,然后论坛都是大价钱的金币,迫于无奈只好来到IBM的官网来寻求指导 http://www.ibm.com/us/en ...
- PHP经典项目案例-(一)博客管理系统5
本篇实现发表博客. 八.发表博客 (1).界面实现file.php <tr> <td colSpan=3 valign="baseline" style ...
- Ipad也怕冷?!
今天,说一Ipad充不了电,我想才没买好久,这么快电池就坏了呀.难道买到歪货了? 它的表现是充电线一接上去,电池指示有反应,也有"闪电"标志,就是充不进去电.本来想打客服的,还是先 ...
- Parse 使用- iOS 后台数据[转]
原文地址:http://blog.csdn.net/vipwangl/article/details/8846415 最近在学习Parse,但是Parse的中文教程比较少,看到这篇英文教程,把它翻译一 ...
- jdbc详解(一)
JDBC简介 l 数据库驱动 SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC l JDBC 全称为: Java Data Base Connectivity ...
- VB总结1-事件过程之键盘鼠标过程
事件过程:参考 (http://baike.baidu.com/view/1523990.htm) 事件是指对象对于外部动作的响应,当对象发生了某个事件,就会执行与此对象的这个事件相应的代码,这段代码 ...
- 用JavaScript 来创建 mac os x 程序这样是否好
在网上看到的文章: 用 JavaScript 编写 OS X 应用 (Tyler Gaw) 这个文章的内容是不错的. 可是思路呢? 我们假设想学一种方法或工具,这样做好吗? 我看了上面的代码.假设 ...
- 〖Windows〗zigbee实验之cygwin编译tinyos.jar编译出错的解决方法
1. 使用的cygwin安装包下载地址:cygwin-files.zip 2. 使用的一些rpm安装包的下载地址:cygwin_cc2430_rpms.zip 3. cygwin的默认安装目录是:C: ...