どちらが良いですか:多くの結合条件または多くのwhere条件?


13

2つのクエリを比較しようとしています。

クエリ1:

SELECT a,b,c,d,e
FROM tableA
LEFT JOIN tableB
ON tableA.a=tableB.a
WHERE tableA.b=tableB.b AND tableA.c=tableB.c  AND tableA.d=tableB.d  AND tableA.e=tableB.e 

クエリ2:

SELECT a,b,c,d,e
FROM tableA
LEFT JOIN tableB
ON tableA.a=tableB.a AND tableA.b=tableB.b AND tableA.c=tableB.c  AND tableA.d=tableB.d  
WHERE tableA.e=tableB.e 

これら2つのクエリで同じ結果が得られると言ってもいいですか?

さらに、最初のクエリが、より大きなWHERE条件を実行するためのより大きなテーブルを作成すると言うのは正しいですか?一方、2番目のケースでは、より単純なテーブルがWHERE適用されたシンプルなテーブルが作成されます。

結果が同じであると仮定すると、どのクエリを優先する必要がありますか?明らかなパフォーマンスの問題はありますか?


3
いいえ、あなたはそう言っているのは正しくありません。それがの場合になりますINNER JOINが、LEFT JOINこれを使用すると異なる結果が返されます。基本的に、あなたは上で追加した条件WHERE2番目のクエリには、あなたを変換するJOINにはINNER JOIN
Lamak

わかった 私はあなたの言うことに従います。編集しINNER JOINてパフォーマンスに関する質問を有効にした場合、
ジェフ

4
INNER JOINの場合、パフォーマンスに違いはありません。ただし、読みやすく、意図を適切に表現するには、で結合条件を使用し、ONでフィルター条件を使用する必要がありますWHERE
アーロンバートランド

@ypercube右、私はその状態を逃した。
ラマク

回答:


10

(意図しているように見える)のINNER JOIN代わりに使用することを考慮した場合LEFT JOIN、これら2つのクエリは機能的に同等です。クエリオプティマイザーは、最も効率的な実行プランに到達するために、クエリプランを作成するときにWHEREFROM句および句の条件を確認および評価し、これらのすべての要因を考慮します。我々が行う場合はEXPLAIN、両方のステートメントに、我々は同じ結果が得られます。

クエリ1

EXPLAIN
SELECT 
  tableA.ColA
  ,tableA.ColB
  ,tableA.ColC
  ,tableA.ColD
  ,tableA.ColE
FROM tableA
  JOIN tableB ON tableA.ColA=tableB.ColA
WHERE 
  tableA.ColB=tableB.ColB 
  AND tableA.ColC=tableB.ColC 
  AND tableA.ColD=tableB.ColD  
  AND tableA.ColE=tableB.ColE

[結果]

| ID | SELECT_TYPE |  TABLE | TYPE | POSSIBLE_KEYS |    KEY | KEY_LEN |    REF | ROWS |                          EXTRA |
------------------------------------------------------------------------------------------------------------------------
|  1 |      SIMPLE | tableA |  ALL |        (null) | (null) |  (null) | (null) |    1 |                                |
|  1 |      SIMPLE | tableB |  ALL |        (null) | (null) |  (null) | (null) |    1 | Using where; Using join buffer |

クエリ2

EXPLAIN
SELECT 
  tableA.ColA
  ,tableA.ColB
  ,tableA.ColC
  ,tableA.ColD
  ,tableA.ColE
FROM tableA
  JOIN tableB ON tableA.ColA=tableB.ColA
  AND tableA.ColB=tableB.ColB 
  AND tableA.ColC=tableB.ColC 
  AND tableA.ColD=tableB.ColD  
WHERE
  tableA.ColE=tableB.ColE

[結果]

| ID | SELECT_TYPE |  TABLE | TYPE | POSSIBLE_KEYS |    KEY | KEY_LEN |    REF | ROWS |                          EXTRA |
------------------------------------------------------------------------------------------------------------------------
|  1 |      SIMPLE | tableA |  ALL |        (null) | (null) |  (null) | (null) |    1 |                                |
|  1 |      SIMPLE | tableB |  ALL |        (null) | (null) |  (null) | (null) |    1 | Using where; Using join buffer |

次のリンクで詳細を確認できます。また、2つのエンジンの動作を比較できるように、SQL 2008の例を作成しました(これは同じです)。

MySQLクエリの例

SQL 2008クエリの例(両方の結果について「実行計画を表示」を確認してください)


詳細な解決策をありがとうございます。INNER JOIN代わりに試しLEFT JOINましたが、10分の1の時間で同じ出力が得られます。同じ出力が得られる理由はわかっていると思いますが、なぜINNER JOINパフォーマンスが向上するのでしょうか?
ジェフ

4
LEFT JOIN外部結合され、それはセットの完全なリターン側のデータセットを制限することはできません(この場合、テーブルAには)そのテーブルからすべての行を取得しようとします。を使用するとINNER JOIN、両方のテーブルでその基準を活用し、データセットを制限できるため、より迅速に収益を得ることができます。
マイクファル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.