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执行的方方面面,都可能存在优化的需求,还是得综合考量。

针对这个问题,目标就很明确了,为了降低消耗,可从业务层面,考虑降低返回的记录数,进而减少返回的数据容量。

近期更新的文章:

什么是Oracle索引扫描的批量回表操作?

降噪耳机的原理

了解一下随机I/O

登录PDB的几种操作

介绍一个检索Oracle各版本新特性的网站

文章分类和索引:

公众号900篇文章分类和索引

以上是关于MySQL中SQL执行慢的一种可能的原因场景的主要内容,如果未能解决你的问题,请参考以下文章

导致SQL执行慢的原因

sql INSERT 执行慢的问题

如何查找MySQL中查询慢的SQL语句

如何查找MySQL中查询慢的SQL语句

如何查找MySQL中查询慢的SQL语句

mysql数据库: 为啥sql语句在查询分析中的执行速度远远快于在应用程序的(而且有时候后者慢的很多)