暂无图片
mysql sql优化
我来答
分享
sky
2020-07-24
mysql sql优化

SELECT
account_name,
FROM_UNIXTIME(
ROUND(request_time / 1000),
‘%Y-%m-%d’
) date,
country_number,
SUM(

			IF (
				need_resend = '0',
				message_size,
				0
			)
		) AS send,
		SUM(
			CASE message_result
			WHEN 'DELIVRD' THEN
				message_size
			ELSE
				0
			END
		) 'success',
		SUM(
			CASE message_result
			WHEN '' THEN
				message_size
			ELSE
				0
			END
		) AS 'unknown',
		SUM(

			IF (
				message_result = 'DELIVRD'
				OR (
					message_result = ''
					AND need_resend = '0'
				),
				(price) *- 1,
				0
			)
		) AS fee
	FROM
		send_message
	WHERE
		request_time >= 1595433600000
	AND request_time <= 1595519999999
	GROUP BY
		message_result,
		account_name
	ORDER BY
		request_time DESC

环境:
centos 7
mysql 5.7.25
表数据量:四千六百万
where结果集:五百一十万

想请问下上面的这个sql应该如何优化?
我的疑惑:
1.从索引角度优化,只能在request_time字段加索引,因为mysql在where中字段进行比较后,后面的字段是不能用到索引的,所以group by的效率不高
2.根据where的request_time查出来的结果集占到表的11%,优化器没有走索引,这个可以通过sql加强制索引解决,但是要改代码,请问还有其他的办法吗?
3.我认为查询字段的处理不合理,但是我把那几个sum的函数去掉之后,查询时间依然没有减少
4.我们经常需要做一段时间内的统计,类似select … from … where xx > … and xx < … order by a,b,请问这种sql应该怎么优化,这个其实和第一点类似,就是在where做了的比较之后,怎样能让group by也提升性能,我目前知道的办法是加上order by null,那sql要是还有其他字段的排序呢,比如第一点的sql

期待有大神能给我解惑,非常感谢!

我来答
添加附件
收藏
分享
问题补充
3条回答
默认
最新
文成

如果where出来的结果集比较大,可能不走索引反而比较快。
如果 request_time 可以设置为唯一性主键,那么可以从主键上获取所有的列字段,可能是最快的。
如果做一段时间的统计,类似于分页统计,那么分页出来的的数据量一般比较小,

select row1,row2 from tab order by row1 limit N,M

可以利用到 first rows特性,但是n越大,查询越慢。

暂无图片 评论
暂无图片 有用 0
sky

但是用强制索引确实会比不走索引快很多。
request_time不能设置为唯一性主键的,因为这是个时间字段,不可能会是唯一的。
我现在是要一段时间内的数据统计,所以虽然where的结果集很大,但是经过group by之后结果集就很少了,就几百条

暂无图片 评论
暂无图片 有用 0
Cui Hulong

1.send_message,need_resend ,request_time 组合索引。
2.单独计算send,success,unknown,fee 状态对应的数据,最后进行合并。
3.结果集(where结果集:五百一十万)还是太大。看看能不能把统计时间压缩
4.‘%Y-%m-%d’ 语句里可以看出是按天统计的。那是否可以之前统计信息 汇总好,保存到另一张表,每天4行数据,那数据量还是,比较少的。需要的时候调用这张表,在计算当天的值。

暂无图片 评论
暂无图片 有用 0
回答交流
提交
问题信息
请登录之后查看
邀请回答
暂无人订阅该标签,敬请期待~~
暂无图片墨值悬赏