2017-11-27 17 views
1

はJOINを使用して、以下のクエリを記述するためのより良い方法はありますか?使用してサブクエリで...代わりにWHEREのJOINまたは

SELECT 
    t1.id 
FROM 
    t1 
WHERE 
    (
     t1.date1 >= (UTC_TIMESTAMP() + INTERVAL - 20 Hour) 
    OR t1.date2 >= (UTC_TIMESTAMP() + INTERVAL - 20 Hour) 
    OR t1.id2 IN (SELECT id FROM t2) 
    OR t1.id3 IN (SELECT id FROM t2) 
    OR t1.id4 IN (SELECT id FROM t2) 
    ); 

更新:のみ日付2はNULL

+0

参加する必要がありますか、単により洗練されたクエリを作成する方法を探していますか? – Mureinik

+1

@Mureinikはい、私の元の意図です。しかし、私は本当にそれがエレガントであるかどうかに関係なく、より速く "より良い"という意味を持っています。 – tatskie

答えて

0

はOR演算は、おそらくあなたの速度を台無しにしようとしていますほとんどの場合、ORはインデックスのパフォーマンスを低下させます。 これは、最も簡潔に変換は同等に参加:

SELECT t1.id 
FROM t1 INNER JOIN t2 ON t2.id IN (t1.id2, t1.id3, t1.id4) 
WHERE t1.date1 >= (UTC_TIMESTAMP() + INTERVAL - 20 Hour) 
    OR t1.date2 >= (UTC_TIMESTAMP() + INTERVAL - 20 Hour) 
; 

INは論理的ORですが、私はより多くの最近のMySQLのバージョンではそれを少し最適化されていると思います。ない場合は、このより良いパフォーマンスかもしれません:

SELECT t1.id 
FROM t1 
    LEFT JOIN t2 AS t2_2 ON t2_2.id = t1.id2 
    LEFT JOIN t2 AS t2_3 ON t2_3.id = t1.id3 
    LEFT JOIN t2 AS t2_4 ON t2_4.id = t1.id4 
WHERE (t1.date1 >= (UTC_TIMESTAMP() + INTERVAL - 20 Hour) 
     OR t1.date2 >= (UTC_TIMESTAMP() + INTERVAL - 20 Hour) 
    ) 
     AND (t2_2.id IS NOT NULL OR t2_3.id IS NOT NULL OR t2_4.id IS NOT NULL) 
; 

をこれは、IDフィールドにORのを避けるため、これらのフィールドにインデックスを利用することができます。ジョインは3倍になるので、やはり遅くなる可能性があります。

1

することができ、私はここにjoinを使用する方法を考えることはできませんが、意図は、クエリは、よりエレガントかつ/または維持しやすいようにすることです場合、コメントによって暗示されるように、あなたができるいくつかのことがあります。

まず、日付条件。日付の最大は、与えられた期間以上である場合には代わりに二度同じ言葉を繰り返すのは、あなただけ確認することができます - date1date2どちらもnullにすることができると仮定します。

第二に、IDが条件。代わりに、あなたは、単一のexists条件を使用することができますに3回同じ用語を繰り返します。私はそれをチェックする便利なMySQLデータベースを持っていないが、チャンスは、それは実際にあなたの元のバージョンよりも高速に実行し、ちょうど見ていないだろうしているクリーナー:

SELECT 
    t1.id 
FROM 
    t1 
WHERE 
    GREATEST(t1.date1, t1.date2) >= (UTC_TIMESTAMP() + INTERVAL - 20 Hour) 
    OR EXISTS (SELECT * FROM t2 WHERE id IN (t1.id2, t1.id3, t1.id4)); 
+0

'date1'または' date2'がNULL可能ならば、これはオリジナルと同等ではありません。 – spencer7593

+0

@ spencer7593良いキャッチ!私は私の答えに明確なコメントを付け加えました。 – Mureinik

関連する問題