web-dev-qa-db-ja.com

どちらのSQLステートメントが高速ですか? (HAVING vs. WHERE ...)

SELECT NR_DZIALU, COUNT (NR_DZIALU) AS LICZ_PRAC_DZIALU
    FROM  PRACOWNICY
    GROUP BY NR_DZIALU
    HAVING NR_DZIALU = 30

または

SELECT NR_DZIALU, COUNT (NR_DZIALU) AS LICZ_PRAC_DZIALU
    FROM PRACOWNICY
    WHERE NR_DZIALU = 30
    GROUP BY NR_DZIALU
41
M_1

理論(つまり、理論的には SQL標準 )では、WHEREは行を返す前に結果セットを制限し、HAVINGはすべての行を取得した後に結果セットを制限します。したがって、WHEREの方が高速です。この点に関して、SQL標準準拠のDBMSでは、条件をWHEREに設定できない場合にのみHAVINGを使用してください(一部のRDBMSの計算列など)。

両方の実行プランを確認して自分で確認できます。これに勝るものはありません(データを使用した特定の環境での特定のクエリの測定)。

70
Vinko Vrsalovic

エンジンによって異なる場合があります。たとえば、MySQLはHAVINGをほぼ最後に適用します。つまり、最適化の余地はほとんどありません。 manual から:

HAVING句は、アイテムがクライアントに送信される直前のほぼ最後に適用され、最適化は行われません。 (LIMITはHAVINGの後に適用されます。)

この動作はほとんどのSQLデータベースエンジンで同じだと思いますが、保証はできません。

9
Eran Galperin

2つのクエリは同等であり、DBMSクエリオプティマイザーすべきはこれを認識し、同じクエリプランを生成します。そうではないかもしれませんが、状況を認識するのはかなり簡単です。そのため、Sybaseでさえも、現代のどのシステムでも対処できると思います。

グループ関数に条件を適用するには、HAVING句を使用する必要があります。そうしないと、WHERE条件に移動できます。例えば。クエリをCOUNT(DZIALU)> 10のグループに制限したい場合は、個々の行ではなくグループに作用するため、条件をHAVINGに入れる必要があります。

5
Mike Woodhouse

WHERE句の方が高速だと思いますが、まったく同じになるように最適化することは可能です。

2
ysth

彼らが最適化すると言うことは、実際に制御を取り、コンピュータに何をすべきかを伝えることではありません。私は、withingの使用がwhere句の代替ではないことに同意します。 sum()などが使用されているグループに適用されるという特別な使用法があり、結果セットを制限して、それ自体がsum()>>であるグループのみを表示する場合。グループで機能すること、行で機能すること。リンゴとオレンジです。したがって、実際には2つの非常に異なる動物であるため、比較するべきではありません。

2
programmer

SQL Serverは同じステートメントを類似のプランに解析するのに十分スマートなので、両方のステートメントは同じパフォーマンスになります。

したがって、クエリでWHEREまたはHAVINGを使用するかどうかは関係ありません。

しかし、理想的には構文的にWHERE句を使用する必要があります。

0
Manoj Pandey