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


164

JOINまたはINを使用すると正しい結果が得られる場合があります...通常、どちらの方がパフォーマンスがよく、その理由は何ですか。実行しているデータベースサーバーによって異なりますか。(私はMSSQLを使用しています)


:)私は実際に私が少し前に同様のものを研究したときに使用した別の記事を探していて、誤ってその記事に出くわしました
AdaTheDev

考えられる
だまさ

回答:


196

一般的に、INそしてJOIN異なる結果をもたらすことができる異なるクエリです。

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ます。

そうでない場合は、INより速くよりJOINDISTINCT

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


そうです、結合する列が一意である場合、同じように実行することは理にかなっています(私の場合)
Polaris878

1
同様に、IN(SELECT DISTINCT ...)または単にIN(SELECT ...)を使用する必要がありますか?
moo

8
@ orlandu63:をIN意味しDISTINCTます。SQL Serverそれに気付くほど賢く、両方のクエリに対して同じプランを生成します。ただし、他RDBMSのがどのように動作するかはわかりません。
Quassnoi、2009

>> INとJOINは異なるクエリであり、異なる結果をもたらす可能性があります。b.colが一意でなくても、この場合に異なる結果が生成される理由を説明できますか?
Abhijeet



6

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

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

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

マーク


私もこれを考えていました... JOINはより一般的なケースであり、最適化される可能性が高いためです
Polaris878

4

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

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

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


4

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

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

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

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

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

インデックスがある場合でも、EXISTSをINよりも速く見つけることがよくあります。これは、データベースシステム(オプティマイザ)、データ、および使用されるインデックスのタイプに特に依存します。


3
MSSqlでは、存在するという事実はINよりも優れているようです。詳細については、explainextended.com / 2009/06/16 / in-vs-join-vs-existsをご覧ください。「EXISTSは1つの行しか返さないため、INよりもEXISTSの方が効率的であると考えられています。 SQL Serverには当てはまりません。上の例からわかるように、EXISTSとINはまったく同じプランを生成します。これは、EXISTSがINよりも柔軟性があるためです。 )しかし、その逆はありません。」
–MicaëlFélix2014

3

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

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

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


1

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


5
すべきか 多分。そうですか?いいえ、私の投稿を参照してください。
cletus 2009
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.