ネット上のSQL記事でINが遅い、EXISTSを使うべきみたいな記事がちらほらあるので調べてみた。
結論 下記サンプルレベルのSQLにおいては実行計画は同じになった。
下記のDBにおいてサンプル例のSQLに近いSQLで確認をしてみたが、実行計画上INとEXISTSに違いはなかった。
このレベルのSQLであればオプティマイザがIN、EXISTSいずれであっても最適なインデックスを使用するようになっているようだ。
・postgreSQL 9.6.3
・MySQL 5.5.17
・Oracle 12.1.0.2
サンプル例
/*
顧客マスタの顧客コードのインデックスを使用し、
お得意様マスタの全ての顧客コードから顧客マスタの顧客コードを検索
*/
select
*
from 顧客マスタ
where 顧客コード in (
select
顧客コード
from お得意様マスタ
)
/*
お得意先マスタの顧客コードのインデックスを使用し、
顧客マスタの全ての顧客コードからお得意先マスタの顧客コードを検索
*/
select
*
from 顧客マスタ
where exists (
select
お得意様マスタ.顧客コード
from お得意様マスタ
where 顧客マスタ.顧客コード = お得意様マスタ.顧客コード
)
ではIN、EXISTSはどちらを使うべきか?
同じならどっちでもいい。が、実際は複雑なSQLにしたときに正しく解釈されないことがある。
SQLをそのまま解釈した場合、INはサブクエリ外のテーブルのインデックス、EXISTSはサブクエリ内のインデックスを使用する。
サンプル例のSQLでIN、EXISTSのどちらかを使う場合、
・顧客マスタの顧客コードのインデックスを使いたい→IN
・お得意様マスタの顧客コードのインデックスを使いたい→EXISTS
となる
※『結論』にも記述したがSQLでどのインデックスを使用するかはオプティマイザが決めている。
そのため特定のインデックスを使用させたいのであれば、必ず実行計画を確認しインデックスが正しく使用されているか確認する必要がある。