解决mysql发送数据慢查询的方法与思路
{问题现象}
使用狮身人面像来支持倒排索引,但是当狮身人面像从MySQL查询源数据时,有成千上万的查询,但是查询速度非常慢,大约是4~5分钟。
{处理过程}
1)解释
在第一个问题中,索引没有构建,所以解释被用来查看查询计划。结果如下:
从解释的结果来看,整个句子的索引设计没有问题。除了第一个表外,其他表也是通过索引访问的,因为业务需要扫描整个表。
2) show processlist;
解释看不到问题。那个地方慢吗
所以我认为使用显示列表来查看SQL语句的执行状态,结果如下:
发现了很长一段时间,查询处于发送数据状态。
找出发送数据状态的含义。原始状态的名称很有误导性。所谓发送数据不是简单地发送数据,而是收集和发送数据。
这里的关键是如何收集数据,原因是:MySQL索引在查询结束后完成,MySQL得到了一堆ID,如果不在索引中列出,MySQL需要返回数据行,将需要返回的客户端数据读出。
3)显示配置文件
为了进一步验证查询的时间分布,使用显示配置文件命令查看详细的时间分布。
首先打开配置;
执行查询后,使用show配置文件查看查询id;
查询query_id查看详情显示简介;
结果如下:
从结果中可以看出,发送数据的状态执行216s
4)检查对比
通过这些步骤,已经确定慢查询是因为在发送数据状态上花费了大量的时间。结合发送数据的定义,将目标集中在查询语句的返回列上。
经调查,最后决定在说明栏,这是设计如下:`描述` varchar(8000)默认为空的评论,游戏说明。
因此,需要对比一下结果不返回描述的结果:
你可以看到,当你不回的描述,查询时间只需要15s,它返回时,它需要216s,两者之间的差别是15倍。
{原则研究}
这个问题很清楚,但原则上我们需要继续探索。
淘宝给出的原则很好的解释:InnoDB使用大字段的文本,对一些斑点最好的建议
关键信息是,当InnoDB的存储格式row_format =紧(或row_format =冗余),InnoDB将只存储的第一个768字节的长度,和剩余的数据将被存储在溢出页。
我们使用show表状态来查看表的相关信息:
可以看出,平均行是1.5K左右,也就是说,1 / 10店将利用溢出存储。一旦以这种方式存储,当返回数据时,数据将被随机读取,从而导致性能急剧下降。
此外,在测试过程中,发现无论多少次的判决执行,甚至整个表的SELECT *倍,该语句的执行速度变化不明显,数据和索引表的总计达150m左右,而整个InnoDB缓冲池有5G,这是足够多的缓存整个表。如果溢出页被缓存,则性能应该大幅度提高。
但结果没有得到改善,所以从这个试验我们可以看出,InnoDB没有缓存溢出(溢出页)到内存页。
这个设计是合理的,因为溢出页是存储在大数据,如果放在缓存中,会有一个大的数据集(BLOB,文本、varchar)查询,可能所有的缓存更新,这将导致其他一般的查询性能急剧下降。
{解}
找到问题的根本原因,解决办法并不困难:
1)在查询时删除描述查询,但这仅限于业务的实现,可能需要较大的业务调整。
2)优化表结构,分到另一个表的说明。这种变化较大,需要对现有业务进行修改。如果业务继续对描述信息进行查询,优化后的性能将不会得到很大改善。
以上是本文的全部内容,希望能对大家有所帮助。