web-dev-qa-db-ja.com

SQL JOIN対INパフォーマンス?

JOINまたはINを使用すると、正しい結果が得られる場合があります。通常、どちらがパフォーマンスが優れているのですか?実行しているデータベースサーバーにどの程度依存しますか? (参考私はMSSQLを使用しています)

150
Polaris878

一般的に、INJOINは異なるクエリであり、異なる結果をもたらす可能性があります。

SELECT  a.*
FROM    a
JOIN    b
ON      a.col = b.col

とは異なります

SELECT  a.*
FROM    a
WHERE   col IN
        (
        SELECT  col
        FROM    b
        )

b.colが一意でない限り。

ただし、これは最初のクエリの同義語です。

SELECT  a.*
FROM    a
JOIN    (
        SELECT  DISTINCT col
        FROM    b
        )
ON      b.col = a.col

結合列がUNIQUEであり、そのようにマークされている場合、これらの両方のクエリはSQL Serverで同じプランを生成します。

そうでない場合、INJOINDISTINCTよりも高速です。

パフォーマンスの詳細については、私のブログのこの記事を参照してください。

181
Quassnoi

おもしろいことに、私はこの非常に主題に関するブログ投稿をしました。

Oracle vs MySQL vs SQL Server:Aggregation vs Joins を参照してください

簡単な答え:テストする必要があり、個々のデータベースは大きく異なります。

26
cletus

言うのはかなり難しいです-どちらがよりうまく機能するかを実際に見つけるには、実行時間を実際にプロファイルする必要があります。

一般的な経験則として、外部キー列にインデックスがあり、(ほとんど)INNER JOIN条件のみを使用している場合、JOINはわずかに高速になると思います。

ただし、OUTER JOINの使用を開始するとすぐに、または外部キーインデックスが不足している場合は、INの方が速くなる場合があります。

マーク

4
marc_s

論理的な違いに関する興味深い記事: SQL Server:JOIN vs IN vs EXISTS-the logical difference

関係とインデックスが維持されると仮定すると、Joinの全体的なパフォーマンスが向上します(他の操作よりもその操作の操作に多くの労力が費やされます)。概念的に考えると、2つのクエリと1つのクエリの違いです。

クエリアナライザに接続し、試して、違いを確認する必要があります。また、クエリ実行プランを見て、手順を最小限に抑えてください。

4
AdamSane

このスレッドはかなり古いですが、まだ頻繁に言及されています。私の個人的な好みとしては、EXISTSキーワードを使用してデータベースに問い合わせる別の方法があるため、それは少し不完全です。

したがって、テーブルaの値のみに関心がある場合は、次のクエリを使用できます。

SELECT  a.*
FROM    a
WHERE   EXISTS (
    SELECT  *
    FROM    b
    WHERE   b.col = a.col
    )

Colがインデックス付けされていない場合、dbはcolで同じ値を持つbのすべてのレコードを検索する必要はなく、最初のレコードを検索するだけでよいため、違いは大きいかもしれません。 b.colにインデックスがなく、bに多くのレコードがある場合、テーブルスキャンが結果になる可能性があります。 INまたはJOINの場合、これは完全なテーブルスキャンになり、EXISTSの場合、これは部分的なテーブルスキャンになります(最初に一致するレコードが見つかるまで)。

Bに同じcol値を持つレコードが多数ある場合、条件が満たされていることを確認するためだけに、これらすべてのレコードを一時スペースに読み込むために多くのメモリを浪費します。存在する場合、これは通常回避できます。

インデックスがある場合でも、INよりもEXISTSの方が速いことがよくあります。データベースシステム(オプティマイザー)、データ、そして最後に使用されるインデックスのタイプに依存します。

3
S.Roeper

各データベースの実装ですが、多かれ少なかれ同じ方法で一般的な問題をすべて解決していると推測できます。 MSSQLを使用している場合は、生成される実行計画を確認してください。これを行うには、プロファイラーと実行計画をオンにします。これにより、コマンドの実行時にテキストバージョンが提供されます。

使用しているMSSQLのバージョンはわかりませんが、クエリアナライザでSQL Server 2000のグラフィカルバージョンを取得できます。この機能は、後のバージョンのSQL Server Studio Managerのどこかに潜んでいると確信しています。

実行計画をご覧ください。もちろん、テーブルが小さい場合を除き、可能な限りテーブルスキャンを避けてください。その場合、テーブルスキャンはインデックスを使用するよりも高速です。それぞれの異なるシナリオが生成するさまざまな結合操作について読んでください。

3
uriDium

オプティマイザーは、通常のクエリに対してどちらの方法でも同じ結果が得られるほど十分にスマートでなければなりません。実行計画を確認すると、同じ結果が得られます。そうでない場合、通常、JOINの方が高速であると考えます。ただし、すべてのシステムは異なるため、システム上のコードをプロファイルして確認する必要があります。

1
Joel Coehoorn