记录一次sql group by 优化记录

最近有个手动任务,需要计算每天的数据量,然后再进行处理。根据这种情况计算,sql是这样的

SELECT FROM_UNIXTIME(publish_time / 1000, '%Y-%m-%d') date,
COUNT(*) as count
FROM
info_article_main
WHERE
publish_time BETWEEN ?
AND ?
GROUP BY date

这个sql的执行计划

在extra字段里可以看到使用了索引,执行临时表,文件排序操作。

type的类型是range,范围查询也走了索引,看起来还不错。

从rows上来看,扫描了接近40w的数据,数据量很大。所以这个sql有时候会执行十几二十几秒的时间,会导致服务之间调用超时。

group by 语句中需要放到临时表上的数据量特别大,却还是要按照“先放到内存临时表,插入一部分数据后,发现内存临时表不够用了再转成磁盘临时表”,看上去就有点儿傻。

针对这种情况,我们可以使用SQL_BIG_RESULT,通知优化器这次查询数据量很大,直接使用磁盘临时表

从 Extra 字段可以看到,这个语句的执行没有再使用临时表,而是直接用了排序算法。

  1. 如果对 group by 语句的结果没有排序要求,要在语句后面加 order by null;

  1. 尽量让 group by 过程用上表的索引,确认方法是 explain 结果里没有 Using temporary 和 Using filesort;

  1. 如果 group by 需要统计的数据量不大,尽量只使用内存临时表;也可以通过适当调大 tmp_table_size 参数,来避免用到磁盘临时表;

  1. 如果数据量实在太大,使用 SQL_BIG_RESULT 这个提示,来告诉优化器直接使用排序算法得到 group by 的结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值