ハマログ

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

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日


関連記事

爆速PHPフレームワーク「Phalcon」をお試し

浅春の候、皆様におかれましては益々ご健勝のこととお慶び申し上げます。 Shinが…

Laravel出力ログファイルの切り替え(またはローテーション)

Laravelの標準ログ(storage/logs/laravel.log)は単…

Laravel EloquentのソートでNULLを最後に持ってくる(MySQL)

Laravel5系+MySQL5のはなし。 Laravel+Eloquentのプ…


← 前の投稿

次の投稿 →