MySQL中SQL执行慢的一种可能的原因场景
Posted bisal
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL中SQL执行慢的一种可能的原因场景相关的知识,希望对你有一定的参考价值。
同事反馈了一个问题,mysql 5.7的环境中,这条SQL非常慢,test表就一万多数据,而且字段tid有索引,
select * from test where tid = 'xxxxx1';
P. S. 屏蔽业务属性,表、字段等均为模拟,旨在说明。
看了下他的执行计划,type=ref,key是tid的单键值索引,ref是const,都是很正常的。
test表数据量1万,实际执行一次如上的SQL,需要10秒才可以返回229条数据,执行计划应该是最优的了。
看下数据分布,'xxxxx1'是记录最多的,229条,'xxxxxx2'排名第二,160条,
select tid, count(*) from test group by tid order by 2 desc;
但是按照'xxxxx2'条件进行检索,返回160条数据,就很快,
select * from test where tid = 'xxxxx2';
有可能是数据量的问题么?
"229/1万"和"160/1万",从过滤性上,应该差距不大。
再看下test的结构,几十个字段,发现了个text类型的字段(detail)。
对比下这两个检索字段值,返回的detail内容,发现'xxxxx1'的detail内容很多,每行detail字段长度是617256个字符,如果*229行,换算一下,所有的detail大约135MB的空间容量,而'xxxxx2'的detail字段长度,只是33个字符,如果*160行,detail大约只占0.005MB,由于单键值tid索引只是包含tid一个字段,因此每次执行,都需要进行回表,才可以得到detail等其他的字段,返回135MB和0.005MB的消耗,显而易见了,
select detail, length(detail) from test where tid = 'xxxxx1';
select detail, length(detail) from test where tid = 'xxxxx2';
为了侧面证明,可以检索除detail外的其他字段(均是int、varchar等类型,无大字段),同样的'xxxxx1'条件,很快返回,
select tid, id, description from test where tid = 'xxxxx1';
因此,有理由相信,之所以'xxxxx1'返回慢,还是因为他要返回的数据中detail大字段的内容导致返回的数据量较大,回表消耗太高。
一条SQL的执行计划正确,未必代表他的执行速度一定很快,SQL执行的方方面面,都可能存在优化的需求,还是得综合考量。
针对这个问题,目标就很明确了,为了降低消耗,可从业务层面,考虑降低返回的记录数,进而减少返回的数据容量。
近期更新的文章:
《降噪耳机的原理》
文章分类和索引:
以上是关于MySQL中SQL执行慢的一种可能的原因场景的主要内容,如果未能解决你的问题,请参考以下文章