INとEXISTSの使い分け

うまさん  
(No.1)
SQLのINとEXISTSの使い分けについて質問させてください
どちらも同じ結果を求められるようなのですが

EXISTS、同じテーブル内での検索では使わない
IN、同じテーブル内の検索でのみ使う
といった使い分けでも大丈夫でしょうか?

チューニングの観点からだと、明確に使い分けされているみたいなのですが、、
INは、外側のテーブルのデータ量が多く、内部のテーブルのデータ量が多い場合に利用する
EXISTSは、外側のテーブルのデータ量が少なく、内部のテーブルのデータ量が多い場合に利用する
2021.04.10 16:54
関数従属さん 
AP シルバーマイスター
(No.2)
ご質問の観点とは違うかもしれませんが、
EXISTS句は存在するかどうかの判定、
IN句は条件の内どれかに当てはまるデータの取得、
ということで以下の使い分けがあるのかと思います。

・IN句は値も使用可能
  SELECT テーブル1.*
    FROM テーブル1
   WHERE テーブル1.項目A IN ('XXX','YYY');

・EXISTS句は複数の結合キー条件による存在判定が可能
  SELECT テーブル1.*
    FROM テーブル1
   WHERE EXISTS (
         SELECT * 
           FROM テーブル2
          WHERE テーブル2.項目A = テーブル1.項目A
            AND テーブル2.項目B = テーブル1.項目B
         );

※IN句、EXISTS句ともに単一キー条件による判定は可能です。
  例えばテーブル2に存在するテーブル1のデータを取得(キーは項目A)だと以下になります。

  (IN句)
  SELECT テーブル1.*
    FROM テーブル1
   WHERE テーブル1.項目A IN (SELECT テーブル2.項目A FROM テーブル2);

  (EXISTS句)
  SELECT テーブル1.*
    FROM テーブル1
   WHERE EXISTS (
         SELECT * 
           FROM テーブル2
          WHERE テーブル2.項目A = テーブル1.項目A
         );
2021.04.11 17:22
うまさん  
(No.3)
複数の条件を指定する場合はEXISTSということですね
ご回答、ありがとうございます
2021.04.11 20:20
GinSanaさん 
AP プラチナマイスター
(No.4)
この投稿は投稿者により削除されました。(2021.04.12 07:47)
2021.04.12 07:47
GinSanaさん 
AP プラチナマイスター
(No.5)
パフォーマンスの話をすると、だいたい目安がINの場合判定対象が1000件超えするとパフォーマンス落ちして(Oracleならそうらしいけど、まずそんな引数を指定しない)・・・とか、
遠い昔はEXISTSの方が(NOT EXISTSではない)速いとかありましたが、いまやオプティマイザの進化によりどっこいです。postgresもいまやどっこいですね。ついでにいうと、IN句の引数は、よく出てくる(引っかけたい)キーワードを左にやっておくと、引っ掛かった時点で検索が終わるので、そういう調整も出来ます。

でも、件数が多いと遅くなる(EXISTSの場合、フルスキャンで見つかった時点で返ってくるので、UNIX/GNU Linuxのgrep -qみたいなもんです)のは確かなので、実際はINNER JOIN(内部結合)で振り落とします。そのほうがよほど速い。
だから、EXISTSって使うか?っていうと、自分はあまり使わないですね。周りは使いたがるんですが・・・。

2021.04.12 07:47
うまさん  
(No.6)
INもEXISTSも処理速度は同じくらいなのですね
さらに、EXISTSよりINNER JOINの方が速いと
DBスペシャリストの取得を目標にしているので勉強になりました
ありがとうございます
2021.04.12 12:43
GinSanaさん 
AP プラチナマイスター
(No.7)
ちなみに、NOT EXISTSの代替は、LEFT JOINして、結合テーブルのカラムがNULLになったものをWHERE句のIS NULLで取ると同じことが出来ます。
2021.04.12 13:22

返信投稿用フォーム

スパム防止のためにスレッド作成日から30日経過したスレッドへの書込みはできません。

その他のスレッド


Pagetop