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. これにより、重複を排除する不要な手順が不要になります。

1 つの行が最大でも 1 つのテキストに一致する場合、次のように動作します。

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 に答える