2016-07-01 12 views
0

MySQLのレコードテーブルを使用すると、 'some_timestamp'のインデックスが存在します。計算されたwhere句のあるMySQLクエリのパフォーマンス

WHERE句は、異なる時間バケットのレコードを数えられるように計算を使用しています。

実行に時間がかかります。

より良い、高速なアプローチはありますか?この場合

set @now = now(); 

(SELECT 
    "45 Days" as "interval", count(*) as "thecount" 
    FROM blah.yada 
    where TIMESTAMPDIFF(day,some_timestamp,@now) <= 45 
     ) 

UNION 
(SELECT 
    "90 Days" as "interval", count(*) as "thecount" 
    FROM blah.yada 
    where TIMESTAMPDIFF(day,some_timestamp,@now) > 45 and TIMESTAMPDIFF(day,event_timestamp,@now) <=90 
     ) 

UNION 
(SELECT 
    "the rest" as "interval", count(*) as "thecount" 
    FROM blah.yada 
    where TIMESTAMPDIFF(day,some_timestamp,@now) > 90 
     ) 

答えて

1

、少しだけは驚異を働かせることができ、あなたのロジックを再加工:

は、ここで現在のコードです。

TIMESTAMPDIFF(day,some_timestamp,@now) <= 45 

some_timestamp >= @now - INTERVAL 45 DAY 

に変更し、その上、あなたの比較の残りの部分とすることができます。計算をフィールド外に移動することにより、索引を使用することができます。


さらに、複数のクエリとUNIONは必要ありません。

SELECT CASE WHEN some_timestamp >= @now - INTERVAL 45 DAY THEN "45 Days" 
      WHEN some_timestamp >= @now - INTERVAL 90 DAY THEN "90 Days" 
      ELSE "the rest" 
     END AS `interval` 
    , COUNT(*) AS `theCount` 
FROM blah.yada 
GROUP BY `interval` 
; 
+0

これは明らかでした。私はよく知っているはずです!ありがとう!!! – Fred

+0

CASEを使用していただきありがとうございます。しかし、このように再構成すると、クエリの完了には1.0秒かかります。醜いUNIONアプローチは、同じ結果を生み出すのにわずか0.3秒しかかかりません。 – Fred

+0

@Fred hmm、奇妙だが、奇妙なことにあまりにも驚くべきことではない。多くの行があると言っていたので、おそらく数百万の文字列でグループ化を実行する必要がありました。あなたが文字列である間隔に "結婚"していないのではなく、代わりにintであれば、はるかに優れているかもしれません。 – Uueerdo