web-dev-qa-db-ja.com

SQLでは結合順序は重要ですか?

パフォーマンスを無視して、以下のクエリAとBから同じ結果が得られますか? CとDはどうですか?

-- A
select *
from   a left join b
           on <blahblah>
       left join c
           on <blahblan>


-- B
select *
from   a left join c
           on <blahblah>
       left join b
           on <blahblan>  

-- C
select *
from   a join b
           on <blahblah>
       join c
           on <blahblan>


-- D
select *
from   a join c
           on <blahblah>
       join b
           on <blahblan>  
157
Ogrish Man

INNER結合の場合、いいえ、順序は関係ありません。 selectをSELECT *からSELECT a.*, b.*, c.*に変更する限り、クエリは同じ結果を返します。


LEFTRIGHTまたはFULL)の場合、OUTER結合、はい、順序が重要です-および(updated)複雑です。

まず、外部結合は可換ではないため、a LEFT JOIN bb LEFT JOIN aと同じではありません

外部結合も結合性ではないため、例では両方の(可換性と結合性)プロパティが関係します。

a LEFT JOIN b 
    ON b.ab_id = a.ab_id
  LEFT JOIN c
    ON c.ac_id = a.ac_id

と同等

a LEFT JOIN c 
    ON c.ac_id = a.ac_id
  LEFT JOIN b
    ON b.ab_id = a.ab_id

しかし:

a LEFT JOIN b 
    ON  b.ab_id = a.ab_id
  LEFT JOIN c
    ON  c.ac_id = a.ac_id
    AND c.bc_id = b.bc_id

とは異なります

a LEFT JOIN c 
    ON  c.ac_id = a.ac_id
  LEFT JOIN b
    ON  b.ab_id = a.ab_id
    AND b.bc_id = c.bc_id

別の(願わくばより単純な)結合性の例。これを(a LEFT JOIN b) LEFT JOIN cと考えてください:

a LEFT JOIN b 
    ON b.ab_id = a.ab_id          -- AB condition
 LEFT JOIN c
    ON c.bc_id = b.bc_id          -- BC condition

この同等a LEFT JOIN (b LEFT JOIN c)に:

a LEFT JOIN  
    b LEFT JOIN c
        ON c.bc_id = b.bc_id          -- BC condition
    ON b.ab_id = a.ab_id          -- AB condition

それは、「いい」ON条件があるからです。 ON b.ab_id = a.ab_idc.bc_id = b.bc_idは両方とも等価性チェックであり、NULLの比較を含みません。

他の演算子、またはON a.x <= b.xまたはON a.x = 7またはON a.x LIKE b.xまたはON (a.x, a.y) = (b.x, b.y)などのより複雑な演算子で条件を設定することもできますが、2つのクエリは同等です。

ただし、これらのいずれかがIS NULLまたはCOALESCE()のようなnullに関連する関数を含む場合、たとえば条件がb.ab_id IS NULLである場合、2つのクエリは同等ではありません。

194
ypercubeᵀᴹ

通常の結合では、そうではありません。 TableA join TableBTableB join TableAと同じ実行計画を作成します(したがって、CとDの例は同じになります)

左右の結合の場合はそうなります。 TableA left Join TableBTableB left Join TableAとは異なりますが、TableB right Join TableAとは同じです

4
Diego

Bに参加する前にBのフィールドでCに参加しようとすると、つまり:

SELECT A.x, A.y, A.z FROM A 
   INNER JOIN C
       on B.x = C.x
   INNER JOIN b
       on A.x = B.x

クエリは失敗するため、この場合は順序が重要です。

0
Teo J.

Oracleオプティマイザーは、内部結合のテーブルの結合順序を選択します。オプティマイザーは、単純なFROM句でのみテーブルの結合順序を選択します。 Uは、WebサイトでOracleのドキュメントを確認できます。そして、左、右のアウタージョインでは、最も投票数の多い回答が正しいです。オプティマイザーは、最適な結合順序と各テーブルの最適なインデックスを選択します。結合順序は、どのインデックスが最良の選択であるかに影響する場合があります。オプティマイザーは、内部テーブルの場合はテーブルのアクセスパスとしてインデックスを選択できますが、外部テーブルの場合はインデックスを選択できません(さらに条件はありません)。

オプティマイザは、単純なFROM句でのみテーブルの結合順序を選択します。 JOINキーワードを使用するほとんどの結合は単純な結合にフラット化されるため、オプティマイザーは結合順序を選択します。

オプティマイザーは外部結合の結合順序を選択しません。ステートメントで指定された順序を使用します。

結合順序を選択するとき、オプティマイザーは次のことを考慮します。各テーブルのサイズ各テーブルで使用可能なインデックス特定の結合順序でテーブルのインデックスが有用かどうか各テーブルでスキャンされる行とページの数参加する

0
Saumyojit Das