优化mysql脚本

ddhy6vgd  于 2021-06-20  发布在  Mysql
关注(0)|答案(3)|浏览(275)

我已经开始了一个新的工作,他们正在使用mysql作为他们的主要数据库。
我更习惯mssql,不知道下面的语句是否可以优化,因为它需要10分钟!
提前感谢任何人能提供的帮助。

SELECT 
CAST(DATE_FORMAT(created_at, '%Y-%m-%d %k:%i:00') 
AS DATETIME) AS 'Date', 
COUNT(*) AS Count 
FROM 
db 
WHERE 
created_at BETWEEN NOW() - INTERVAL 5 HOUR AND NOW() 
AND status = 'Accepted' 
GROUP BY CAST(DATE_FORMAT(created_at, '%Y-%m-%d %k:%i:00') 
AS DATETIME)
ycggw6v2

ycggw6v21#

索引 (status, created_at) 将优化 WHERE 此查询的一部分(范围前的常量)。
您的分组似乎表明您希望按分钟分组 created_at . 基于此表达式创建生成的列并将其附加到索引将有助于 GROUP BY 本条款的一部分(以及 GROUP BY 应引用此生成的列,而不是表达式)。

alter table db add minute bigint unsigned as (to_seconds(created_at) div 60),
                 add index status_created_at_min (status, created_at, minute);

以及生成的查询:

SELECT 
CAST(DATE_FORMAT(created_at, '%Y-%m-%d %k:%i:00') 
AS DATETIME) AS 'Date', 
COUNT(*) AS Count 
FROM 
db 
WHERE 
created_at BETWEEN NOW() - INTERVAL 5 HOUR AND NOW() 
AND status = 'Accepted' 
GROUP BY minute;
368yc8dk

368yc8dk2#

不知道为什么要在select或group by中执行强制转换,但将最后一行替换为:

GROUP BY DATE_FORMAT(created_at, '%Y-%m-%d %k:%i')

如果这没有多大帮助,请在该命令之前添加“explain”,检查输出。如果你不能用explain前缀来解释,就把它贴在这里,这样就有人可以给你关于索引的建议了。

gtlvzcf8

gtlvzcf83#

这可能会加快一些速度,因为它会照顾到 WHERE :

INDEX(status, created_at)   -- in this order

如果您创建了一个“generated”列(正如danblack所建议的),那么只使用查询和索引中的generated列就可以更进一步了。这样,它就变成了一个“覆盖”索引,因此查询完全在索引中执行:

INDEX(status, minute)   -- in this order

如果这还不够。。。
具有“报告”的大型表通常受益于创建和维护“摘要表”。与其他一些供应商不同,没有内置的机制来实现这一点。看看这个。

相关问题