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のデータ量がほぼ同じ場合、パフォーマンスがほぼ同じなのでどちらでもいい。