2

我有一个查询(有效)来显示对包含特定关键字的消息的平均回复数。

但我认为它可以被优化——我们担心随着数据库的增长,这个查询会变得非常慢,特别是如果我们使用更大的日期范围。

这是当前查询的示例:

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%'添加了大量冗余代码。有什么优化思路吗?- 非常感谢所有建议

4

2 回答 2

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 
于 2012-11-29T17:40:56.993 回答
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
于 2012-11-29T18:36:18.223 回答