Spring Boot DB連携

Oracle上でWHERE句内でIN句を利用した場合とEXISTS句を利用した場合の性能を測定してみた

SQLのWHERE句でレコードの存在チェックを行う時などの表現を、IN句でもEXISTS句でも行えるが、EXISTS句は条件に一致するレコードが1件でもあればそこで処理を終了するのに比べて、IN句は条件に当てはまるデータを全て抽出するため、EXISTS句を利用した方が処理が速くなることが多い。

今回は、WHERE句内でIN句を利用した場合とEXISTS句を利用した場合それぞれで、SQLの実行速度を測定するプログラムを作成してみたので、共有する。

なお、SQL文の性能改善を行う方法については、以下のサイトを参照のこと。
https://sites.google.com/site/orapeform/sql_minaoshi

前提条件

下記記事の実装が完了していること。

Oracle上でselect文で「*」を利用した場合とカラム名を利用した場合の性能を測定してみたSQL SELECT文を記載する際、「SELECT *」よりは「SELECT (カラム名)」を、「SELECT COUNT(*)」よりは...

サンプルプログラムの作成

作成したサンプルプログラムの構成は、以下の通り。
サンプルプログラムの構成
なお、上記の赤枠は、前提条件のプログラムから変更したプログラムである。

Mapperインタフェース・Mapper XMLの内容は以下の通りで、IN句を利用した場合・EXISTS句を利用した場合それぞれで、生年月日が基準日と一致するデータを取得するSQLを用意している。

また、サービスクラスのサブクラスの内容は以下の通りで、それぞれのSQLを呼び出し、それぞれの実行時間を表示するようにしている。

その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-oracle-performance-in-exists/demo



ウズウズカレッジJavaコースはわかりやすい動画教材と充実した就業サポートで優良企業を目指せるプログラミングスクールだったJavaは、世界中で広く使われていて、現在の需要が高く将来性もある開発言語になります。 https://www.acrovision....

サンプルプログラムの実行結果

サンプルプログラムの実行結果は以下の通りで、IN句よりEXISTS句を利用した方が、SQLが速くなることが確認できる。

1) 以下を実行し、USER_DATAテーブルに、生年月日が2012/1/20のデータ50,000件と、生年月日が2012/1/21のデータ50,000件のデータを、それぞれ追加する。

サンプルプログラムの実行結果_1_1

実行後、以下のように、レコード数が100,000件で、そのうち、生年月日が2012/1/20であるデータが50,000件になっていることが確認できる。
サンプルプログラムの実行結果_1_2

サンプルプログラムの実行結果_1_3

2) 1)の状態でSpring Bootのメインクラス(DemoApplication.java)を実行した結果、コンソールログに出力される内容は以下の通り。

<1回目>
サンプルプログラムの実行結果_2_1

<2回目>
サンプルプログラムの実行結果_2_2

要点まとめ

  • SQLのWHERE句でIN句でもEXISTS句の両方が利用できる場合、EXISTS句は条件に一致するレコードが1件でもあればそこで処理を終了するのに比べて、IN句は条件に当てはまるデータを全て抽出するため、EXISTS句を利用した方が処理が速くなることが多い。