ハマログ

株式会社イーツー・インフォの社員ブログ

SQLでinとexistsの話

 最近開発した時、sqlも使いました。使った時、inとexistsの区別が分からないですが、結果は同じなのであんまり考えなかった。今日はいろいろ調べて、inとexistsの違いを纏めます。

 まずは結論を出します。

 1、テーブルB(副問合せ)はテーブルA(親問合せ)よりデータ量が少ない場合はinが使う

 2、テーブルBはテーブルAよりデータ量が多い場合はexistsが使う

 3、テーブルBとテーブルAのデータ量がほぼ同じ場合はどちらでもいい

 in:

 select * from A

 where id in(select id from B)

 inが使う時、先に副問合せの(select id from B)を実行して、取れた結果をキャッシュで保存されて、ループでBから取れた結果とテーブルAに比べて、最後に比べた結果を結果リストに保存します。

 Javaコードは下記ような感じと思います:

 List resultSet=[];

 Array A=(select * from A);

 Array B=(select id from B);

 for(int i=0;i<A.length;i++) {

    for(int j=0;j<B.length;j++) {

        if(A[i].id==B[j].id) {

           resultSet.add(A[i]);

           break;

    }

  }

 }

 return resultSet;

 ソースから読んで、テーブルBは全てデータをループしてトラバーサルしますので、システムパフォーマンスを考えると、テーブルBはテーブルAよりデータ量が少ない場合はinが一番いいと思います。

 exists:

 select a.* from A a

 where exists(select id from B b where a.id=b.id)

 existsが使う時、先に副問合せの(select id from B b where a.id=b.id)を実行して、結果が保存しなくて、trueとfalseのみをreturnします。(結果がある場合trueをreturnする)

 そしてJavaコードは下記ような感じです:

 List resultSet=[];

 Array A=(select * from A)

 for(int i=0;i<A.length;i++) {

    if(exists(A[i].id) {    //(select id from B b where a.id=b.id)はtrue或いはfalseをreturn

        resultSet.add(A[i]);

    }

 }

 return resultSet;

 そして、テーブルBはテーブルAよりデータ量が多いでも、A.length回をトラバーサルしますので、テーブルBはテーブルAよりデータ量が多い場合existsが一番いい。

 テーブルBとテーブルAのデータ量がほぼ同じ場合、パフォーマンスがほぼ同じなのでどちらでもいい。

 
sql

  Lxx   2019年11月8日


関連記事

マイクロサービスアーキテクチャへの取り組み

はじめに ”マイクロサービスアーキテクチャ”という言葉も、随分普及してきました。…

Github Copilot for Businessが一般提供されたので導入しました

2021年にプレビューリリースされ、その後一般リリースされたGithub Cop…

Laravel4でHTTPステータスコードを設定する

Laravel4でのHTTPステータスコードの設定方法。 HTTPステータスコー…


← 前の投稿

次の投稿 →