前言:
最近在测试环境中点击一个图表展示页面时,半天才得到后台响应的数据进行页面渲染展示,后台的响应很慢,这样极大的降低了用户的体验;
发现这个问题后马上进行了排查 ,通过排查发现是由一个查询很慢的 group by 语句导致的;
本文主线:
①、简单描述下排查步骤;
②、对 group by 查询慢进行优化;
简单描述下排查步骤:
排查主要分为了两个步骤:
后台接口的监控,看看哪个方法调用时耗时多
数据库开启慢查询日志,记录执行很慢的SQL
推荐使用阿里开源的Java线上诊断工具 Arthas ,使用其 trace 命令统计方法调用链路上各个方法节点的耗时;
Arthas 工具的具体使用方法可参考: 线上服务响应时间太长的排查心路 ;
通过使用Arthas工具统计到一个进行数据库的 group by查询 方法耗时很严重;
为了进一步确定是这个查询SQL 很耗时,将MySql 的慢查询日志开启了,然后再次调用后台这个接口,发现慢查询日志中确实存在了这个SQL语句;
SQL语句如下:
SELECT
date_format(createts, '%Y') AS YEAR
FROM
t_test_log
GROUP BY
date_format(createts, '%Y')
ORDER BY
createts DESC
这个SQL语句是用来统计表中所有数据被创建时的年份;
下面就来聊聊这个SQL为什么会比较慢,然后进行了怎样的优化;
对 group by 查询慢进行优化:
在优化group by查询的时候,一般会想到下面这两个名词,通过下面这两种索引扫描可以高效快速的完成group by操作:
松散索引扫描(Loose Index Scan)
紧凑索引扫描(Tight Index Scan)
group by操作在没有合适的索引可用时,通常先扫描整个表提取数据并创建一个临时表,然后按照group by指定的列进行排序;在这个临时表里面,对于每一个group 分组的数据行来说是连续在一起的。
完成排序之后,就可以得到所有的groups 分组,并可以