[英]Optimising a MySQL query with UNIONS
I've got a query (which works) to show the average number of replies to messages containing specific keywords. 我有一个查询(有效)以显示对包含特定关键字的邮件的平均答复数。
But I think it could be optimised - we're worried that as the database grows this query will become very slow, especially if we use a larger date range. 但是我认为它可以进行优化-我们担心随着数据库的增长,此查询将变得非常慢,尤其是当我们使用较大的日期范围时。
Here's a sample of the current query: 这是当前查询的示例:
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
As you can see, the only thing that really changes is the WHERE message.text LIKE '%text1%'
which adds lots of redundant code. 如您所见,唯一真正改变的是WHERE message.text LIKE '%text1%'
,它添加了许多冗余代码。 Any optimisation ideas? 有什么优化想法吗? - all advice much appreciated -非常感谢所有建议
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
To make your query perform better, use UNION ALL
instead of UNION
. 为了使查询性能更好,请使用UNION ALL
而不是UNION
。 This will eliminate the unnecessary step of eliminating duplicates. 这将消除消除重复项的不必要步骤。
If one row can match at most one of the texts, then the following will work: 如果一行最多可以匹配其中一种文本,则可以使用以下内容:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.