我有一个查询(可行),以显示包含特定关键字的邮件的平均回复数。
但我认为它可以被优化 - 我们担心随着数据库的增长,这个查询会变得非常慢,特别是如果我们使用更大的日期范围。
以下是当前查询的示例:
SELECT 'text1' AS "text", ROUND(AVG (a.rt_count),2) AS "Average over 100 days"
FROM
(SELECT COUNT(reply.id) AS rt_count
FROM message LEFT OUTER JOIN reply ON (message.id = reply.message)
WHERE message.text LIKE '%text1%'
AND message.created_date >= (CURDATE() - INTERVAL 100 DAY)
GROUP BY message.id
) AS a
UNION
SELECT 'text2' AS "text", ROUND(AVG (a.rt_count),2) AS "Average over 100 days"
FROM
(SELECT COUNT(reply.id) AS rt_count
FROM message LEFT OUTER JOIN reply ON (message.id = reply.message)
WHERE message.text LIKE '%text2%'
AND message.created_date >= (CURDATE() - INTERVAL 100 DAY)
GROUP BY message.id
) AS a
UNION
SELECT 'text3' AS "text", ROUND(AVG (a.rt_count),2) AS "Average over 100 days"
FROM
(SELECT COUNT(reply.id) AS rt_count
FROM message LEFT OUTER JOIN reply ON (message.id = reply.message)
WHERE message.text LIKE '%text3%'
AND message.created_date >= (CURDATE() - INTERVAL 100 DAY)
GROUP BY message.id
) AS a
正如您所看到的,唯一真正改变的是WHERE message.text LIKE '%text1%'
,这会增加许多冗余代码。任何优化想法? - 所有建议非常感谢
答案 0 :(得分:1)
SELECT case when message.text like '%text1%'
then 'text1'
when message.text like '%text2%'
then 'text2'
when message.text like '%text3%'
then 'text3'
end AS "text",
ROUND(AVG (a.rt_count),2) AS "Average over 100 days"
FROM
(SELECT COUNT(reply.id) AS rt_count
FROM message LEFT OUTER JOIN reply ON (message.id = reply.message)
WHERE (message.text like '%text1%'
or message.text like '%text2%'
or message.text like '%text3%')
AND message.created_date >= (CURDATE() - INTERVAL 100 DAY)
GROUP BY message.id
) AS a
答案 1 :(得分:0)
要使您的查询效果更好,请使用UNION ALL
代替UNION
。这将消除不必要的消除重复的步骤。
如果一行最多可以匹配一个文本,那么以下内容将起作用:
SELECT MatchText AS "text", ROUND(AVG (a.rt_count),2) AS "Average over 100 days"
FROM (SELECT MatchText, m.Id, COUNT(reply.id) AS rt_count
FROM (select m.*,
(case when m.text like '%text1%' then 'Text1'
when m.text like '%text2%' then 'Text2'
when m.text like '%text3%' then 'Text3'
end) as MatchText
from message m
) m LEFT OUTER JOIN
repl
ON (m.id = reply.message)
WHERE MatchText is not NULL AND
message.created_date >= (CURDATE() - INTERVAL 100 DAY)
group by MatchText, m.Id
) t
group by MatchText