mysql group by 效率测试及优化

1. mysql group by 效率

总条数: 2千万+
条件区间总条数: 10万+ 去重后大约 9万+条

select create_time from table_name where create_time > 'start' and create_time < 'end' group by order_id limit 2100, 30

耗时: 193864 ms (3分钟左右)

结论: group by 通过explain 查看没有使用到合适的索引(icreate_time),而是选错到其他的索引,导致耗时过长。

2. 优化-指定正确索引

select create_time from table_nameFORCE INDEX(icreate_time) where create_time > 'start' and create_time < 'end' group by order_id limit 2100, 30

耗时: 966 ms

结论: 在手动指定正确的索引后,优化带来的提升是非常明显。

其他: 当然如果手动指定索引不优雅,可以考虑建立一个与区间与group by相关单独的索引。

3. 进行offset测试

select create_time from table_name FORCE INDEX(icreate_time) where create_time > 'start' and create_time < 'end' group by order_id limit 90000, 50

手动指定索引,进行大offset分页查询耗时测试结果
耗时: 667ms

结论: 在正确使用索引的情况下(type: range),大offset分页效率还能接受

4. 优化-消除filesort

通过limit offset 指定相近但不同的参数,尽量避免查询缓存。

select create_time from table_name FORCE INDEX(icreate_time) where create_time > 'start' and create_time < 'end' group by order_id
limit 81310, 1000
耗时: 1763 ms
limit 83310, 1000
耗时:1713 ms
limit 89310, 1000
耗时:1755 ms

加 order by null explain查看,去除 filesort

order by null limit 85310, 1000
耗时:1145 ms
order by null limit 87310, 1000
耗时:1135 ms
order by null limit 80310, 1000
耗时:1143 ms

其他数据集测试:在每次查询结果集 10 100 1000时,它们的总耗时与优化效果值也基本相同,从测试情况来看与返回结果集大小无关。

结论: 加order by null 消除filesort,sql语句效率 40%左右的提升。


原文链接:https://www.jianshu.com/p/7c374713bd8f