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


189

パフォーマンスを無視すると、以下のクエリ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>  

11
なに<blahblah>?AからBとAからCに参加していますか、それともAからBとBからCに参加していますか?
beny23 2012年

2
こんにちは、ベニー、私の質問のコードは抽象化です。AをBに、またはAをCに結合することには関心がありません。同じような構文で同じ結果が得られるかどうかを知りたいだけです。
学習者のみ2012年

回答:


225

以下のためにINNER参加し、いいえ、順序は重要ではありません。選択をからSELECT *に変更する限り、クエリは同じ結果を返しますSELECT a.*, b.*, c.*


LEFTRIGHTまたはFULLOUTER結合の場合、はい、順序が重要です-(更新された)ものははるかに複雑です。

まず、外部結合は可換でa LEFT JOIN bはないので、b 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.xON a.x = 7ON a.x LIKE b.xor ON (a.x, a.y) = (b.x, b.y)、or 、or などのより複雑な演算子を使用して条件を設定することもできますが、2つのクエリは同等です。

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


3
述部がIS NULLまたは「ヌルに関連する関数」。前者の記述は満​​たすが後者は満たさない述語は次のように簡単に想像できますa.somecol > 0 OR b.someothercol > 0。関連付けはその条件で失敗する可能性があります。
Mark Amery 2013年

しかし、そうです、述語が私がここで説明する条件のいずれかを満たさない限り、OUTER JOINが結合的であると言うことは技術的に正しいと思います:stackoverflow.com/questions/20022196/…(最初の結合性も壊れます) INNER JOINの場合ですが、それを壊すための安くて明白なアプローチであるため、言及する価値はありません。最も一般的な種類のJOIN(外部キーでのJOIN)は、これらの条件のいずれも満たさないことを指摘する価値もあります。したがって、素晴らしく、関連性があります。
Mark Amery 2013年

1
@MarkAmeryありがとう、私はその時点で文章を構成するのに苦労していました(そして私はすでにあなたの回答に賛成しています;)
ypercubeᵀᴹ2013年

私が持っているypercube INNER JOIN以下をいますLEFT JOIN。それは最初にクエリがFilterベースのレコードを実行しINNER JOIN、次にレコードに適用LEFT JOINされるように機能しFilteredますか?
ムハンマドババール2015

実際、すべての結合タイプ、SQL標準で指定されているように、また連想性の数学的定義に従って連想ですが、そうではありません。ように、関連付けられていますが、括弧を再配置するとON句(「結合指定」)を新しい場所に移動する必要があるため、関連付け表示され。ただし、これは構文のみです。関係代数表記(結合仕様が結合演算子の下に配置されている)を使用すると、結合性がより明確になります。あなたの議論は、外部結合が可換ではないことを示しているだけで、これは正しいです
Lukas Eder

4

通常の結合の場合は、そうではありません。TableA join TableBと同じ実行プランを生成しTableB join TableAます(CとDの例は同じになります)

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


4
これは可換性のみを扱いますが、質問の例は、質問者が結合性に関心があることを示しています。ypercubeの回答は両方に対応しています。
Mark Amery 2014

2

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

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


はい、これは正しいです。正しい答えを修正する必要があります。
Nir Pengas

-2

Oracleオプティマイザーは、内部結合のテーブルの結合順序を選択します。オプティマイザは、単純なFROM句でのみテーブルの結合順序を選択します。Uは彼らのウェブサイトでオラクルのドキュメントをチェックすることができます。そして、左、右の外部結合の場合、最も投票された答えは正しいです。オプティマイザーは、各テーブルの最適な結合順序と最適なインデックスを選択します。結合順序は、どのインデックスが最良の選択であるかに影響を与える可能性があります。オプティマイザは、内部テーブルの場合はテーブルのアクセスパスとしてインデックスを選択できますが、外部テーブルの場合は選択できません(それ以上の修飾がない場合)。

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

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.