JOINまたはINを使用すると正しい結果が得られる場合があります...通常、どちらの方がパフォーマンスがよく、その理由は何ですか。実行しているデータベースサーバーによって異なりますか。(私はMSSQLを使用しています)
JOINまたはINを使用すると正しい結果が得られる場合があります...通常、どちらの方がパフォーマンスがよく、その理由は何ですか。実行しているデータベースサーバーによって異なりますか。(私はMSSQLを使用しています)
回答:
一般的に、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
より速くよりJOIN
上DISTINCT
。
パフォーマンスの詳細については、私のブログのこの記事を参照してください。
IN
意味しDISTINCT
ます。SQL Server
それに気付くほど賢く、両方のクエリに対して同じプランを生成します。ただし、他RDBMS
のがどのように動作するかはわかりません。
面白いことに、私はこの件についてブログ投稿をしました。
Oracle vs MySQL vs SQL Server:Aggregation vs Joinsを参照してください
短い答え:あなたはそれをテストする必要があり、個々のデータベースは大きく異なります。
それを言うのはかなり難しいです。どちらがより適切に機能するかを実際に見つけるには、実際に実行時間をプロファイルする必要があります。
一般的な経験則として、外部キー列にインデックスがあり、INNER JOIN条件のみ(またはほとんど)を使用している場合、JOINはわずかに高速になると思います。
ただし、OUTER JOINの使用を開始するとすぐに、または外部キーインデックスが不足している場合は、INの方が速い場合があります。
マーク
論理的な違いに関する興味深い記事:SQL Server:JOIN vs IN vs EXISTS- 論理的な違い
リレーションとインデックスが維持されていると仮定すると、Joinは全体的にパフォーマンスが向上します(他の操作よりも多くの労力がその操作で使用されます)。概念的に考えると、2つのクエリと1つのクエリの違いです。
クエリアナライザーに接続して試して、違いを確認する必要があります。また、クエリ実行プランを確認し、手順を最小限に抑えてください。
このスレッドはかなり古いですが、まだ頻繁に言及されています。私の個人的な好みとしては、少し不完全です。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よりも速く見つけることがよくあります。これは、データベースシステム(オプティマイザ)、データ、および使用されるインデックスのタイプに特に依存します。
各データベースの実装ですが、多かれ少なかれ同じ方法で一般的な問題をすべて解決していると思います。MSSQLを使用している場合は、生成される実行プランを確認してください。これを行うには、プロファイラーと実行プランをオンにします。コマンドを実行すると、テキストバージョンが表示されます。
使用しているMSSQLのバージョンはわかりませんが、SQL Server 2000のクエリアナライザーでグラフィカルバージョンを取得できます。この機能は、後のバージョンのSQL Server Studio Managerのどこかに潜んでいると思います。
実行計画をご覧ください。もちろんテーブルが小さい場合を除いて、テーブルスキャンはできるだけ避けてください。テーブルが小さい場合、テーブルスキャンの方がインデックスを使用するより高速です。さまざまなシナリオごとに生成されるさまざまな結合操作について調べます。
オプティマイザは、通常のクエリでどちらの方法でも同じ結果が得られるほど十分にスマートでなければなりません。実行計画を確認すると、同じことができるはずです。そうでない場合は、通常、JOINの方が高速であると考えます。ただし、システムはすべて異なるため、確実にシステムのコードをプロファイルする必要があります。