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时,它们的总耗时与优化效果值也基本相同,从测试情况来看与返回结果集大小无关。