2009-04-24 9 views
30

JOINのON句の基準をどのように並べるのかは重要ですか?JOINのON句で参照されるテーブルの順序は重要ですか?

select a.Name, b.Status from a 
inner join b 
on b.ID = a.StatusID 

select a.Name, b.Status from a 
inner join b 
on a.StatusID = b.ID 

パフォーマンスへの影響はありますか?複数の基準がある場合はどうなりますか?

1つの注文を別の注文よりも保守しやすいですか?

答えて

33

JOIN順序はFROM句で正しい順序でテーブルを置くことによって強制することができます。

  1. MySQLは順序物を作るSTRAIGHT_JOINと呼ばれる特別な条項を持っています。

    このb.idのインデックスを使用します:

    SELECT a.Name, b.Status 
    FROM a 
    STRAIGHT_JOIN 
         b 
    ON  b.ID = a.StatusID 
    

    をし、これがa.StatusIDにインデックスを使用します:

    SELECT a.Name, b.Status 
    FROM b 
    STRAIGHT_JOIN 
         a 
    ON  b.ID = a.StatusID 
    
    • OracleJOIN順序を強制するために特別なヒントORDEREDがあります

    このb.idにインデックスを使用するか、b上のハッシュテーブルを構築します:

    SELECT /*+ ORDERED */ 
         * 
    FROM a 
    JOIN b 
    ON  b.ID = a.StatusID 
    

    そして、これがa.StatusIDにインデックスを使用するか、a上のハッシュテーブルを構築します:

    SELECT /*+ ORDERED */ 
         * 
    FROM b 
    JOIN a 
    ON  b.ID = a.StatusID 
    
    • SQL Server
    というFORCE ORDERというヒントがあります3210

    このb.idにインデックスを使用するか、b上のハッシュテーブルを構築します:

    SELECT * 
    FROM a 
    JOIN b 
    ON  b.ID = a.StatusID 
    OPTION (FORCE ORDER) 
    

    そして、これがa.StatusIDにインデックスを使用するか、a上のハッシュテーブルを構築します:

    SELECT * 
    FROM b 
    JOIN a 
    ON  b.ID = a.StatusID 
    OPTION (FORCE ORDER) 
    
    • PostgreSQLみんな、すみません。あなたのTODO list言う:

    オプティマイザ・ヒント(望まれない)

    オプティマイザヒントは、オプティマイザでの問題を回避するために使用されています。むしろ問題が報告され、修正されることになります。

比較して順序としては、それがどのRDBMSには関係ありません

、私の知る限り。

私は個人的には常に、どの列が検索されるか見積もり、この列を左に置くことを試みますが(lvalueのように見えます)。

詳細はthis answerを参照してください。

+2

+1 –

+1

公式のTODO http://wiki.postgresql.org/wiki/Todo#Features_We_Do_Not_Wantにある "PostgreSQLの人、ごめんなさい" - "オプティマイザのヒント"について。 –

+0

@Milen:もう一度申し訳ありません:) – Quassnoi

8

いいえ、それはありません。

2番目の例は、わかりやすくするためです。

5

いいえデータベースは、基準全体に基づいて最適な実行計画を決定し、各項目を順番に見て作成するのではなく、最適な実行計画を決定する必要があります。これを確認するには、両方のクエリの実行計画を要求することで、それらが同じであることがわかります(同じロジックを最終的に指定する限り、大幅に異なるクエリでも、同じ実行計画にコンパイルされることが多い)。

1

いいえありません。一日の終わりには、本当にa = bであるかどうかを評価するだけです。

と平等の対称性として、状態:任意の量のAおよびBの

  • を、= B、次いでB =場合。

(12)*=12または12=(12)*を確認するかどうかは、論理的に違いはありません。

値が等しい場合は、結合しない場合は結合しません。そして、あなたの最初の例や2番目の例のように指定しても、違いはありません。

1

Read this

のSQLServerは、はるかに複雑なこれ以上の状況の最適化が含まれています。あなたが複数の基準を持っている場合は

ものが評価され、通常は怠惰である(しかし、私は、もしあればエッジケースを中心に研究のビットを行う必要があります。)

可読性のために

私は通常、私はそれを考える

SELECT Name, Status FROM a 
JOIN b 
ON a.StatusID = b.ID 

を好みます変数が宣言されたのと同じ順序で参照するのが良いですが、実際には個人的な趣味です。

1

私はあなたの第二の例を使用していないだろう唯一の理由:

select a.Name, b.Status 
from a 
inner join b 
    on b.ID = a.StatusID 

あなたのユーザーが戻ってくると、「私は、彼らが何のステータスレコードを持っていないすべてのa.nameの場合でも見ることができると言う可能性が高いのですか? ' 「名前のレコードがないのにb.statusのすべてを見ることはできますか」ではなく、この例を前もって計画するために、LEFT外部結合を予期してOn a.StatusID = b.IDを使用します。これは、 'b'なしでテーブル 'a'レコードを持つことができると仮定しています。

訂正:結果は変更されません。

これは、ユーザーが要件を変更したくないため、おそらく疑問点です。

+1

LEFTまたはRIGHT結合でも順序は関係ありませんので、実際には違いはありませんこの場合は私が見ることができます。 ON句が "b.ID = a.StatusID"であってもLEFT OUTER JOINに変更することはできます。 –

+1

@Tom - これを指摘してうれしいです。私はほとんどパニック発作を起こしました。 –

0

いいえ、問題ありません。しかし、ここで別の行にある各テーブルの参照は別の行にある

select a.*, b.* 
from tableA a 
    inner join tableB b 
      on a.name=b.name 
       and a.type=b.type 

(少なくとも私には)クエリを読みやすくするのに役立つ例だし、それぞれが基準に参加。タブブッブは、何がまっすぐなのかを維持するのに役立ちます。

私がしたいことは、私のon文の条件をテーブルと同じ順序にすることです。 aが最初にb、aが左側に、bが右側にあります。

1

多くの人が言ったように、注文は結果やパフォーマンスに違いはありません。

私が指摘したいのは、LINQ to SQLは、最初のケースのみを許可します。

例えば、次の例は、うまく機能...

var result = from a in db.a 
      join b in db.b on a.StatusID equals b.ID 
      select new { Name = a.Name, Status = b.Status } 

...これは、Visual Studioでエラーがスローされながら:

これらのコンパイラエラースロー
var result = from a in db.a 
      join b in db.b on b.ID equals a.StatusID 
      select new { Name = a.Name, Status = b.Status } 

  • CS1937:名 '名前' 'をの左側の範囲ではありませんと等しい。 'equals'のどちらかの側で式を交換することを検討してください。
  • CS1938:名前 'name'は、 'equals'の右側にはありません。 'equals'のどちらかの側で式を交換することを検討してください。

標準SQLのコーディングとは関係ありませんが、どちらか一方に慣れているときには、これは考慮すべき点です。

関連する問題