LoginSignup
10
9

More than 5 years have passed since last update.

PostgreSQLにJDBC APIのPreparedStatementでクエリを実行するときの注意点

Posted at

PostgreSQL JDBC Driverを使ってクエリを投げる際に過去にハマった点をメモしておきます。

PreparedStatementの性能傾向が変わる?

PreparedStatementオブジェクトを作ってクエリを繰り返し実行していると、ある時点から急にクエリ性能が良くなる場合があります。

これは、PostgreSQL JDBC Driverの仕様で、一定回数以上同じPreparedStatementオブジェクトでクエリ実行を繰り返すと、PostgreSQLサーバ側にクエリがキャッシュされてさらに高速化されるためです。

つまり、PostgreSQL JDBC Driverを使っている場合、PreparedStatementによるクエリ実行の最適化には2段階あって

  1. クライアント側の最適化
  2. クライアント側 + PostgreSQLサーバ側の最適化

となっています。
特に、PostgreSQLサーバ側の最適化の影響が大きく、これによりSQL文のパースや実行計画作成がスキップされるため、2.の段階になった瞬間に性能が向上しやすくなります。

で、1.から2.にグレードアップするのがデフォルト設定では5回目からです。このしきい値は変更可能です。

  • PostgreSQLの接続URLにてパラメータprepareThreshold = intで指定する。クエリ全体に影響。
  • PreparedStatementオブジェクトごとにvoid setPrepareThreshold(int threshold)メソッドで指定する。

詳細は、ドキュメント参照のこと。
https://jdbc.postgresql.org/documentation/head/server-prepare.html
https://jdbc.postgresql.org/documentation/head/connect.html

PreparedStatementって?

ややこしいことにPostgreSQLサーバ側のクエリキャッシュ機構もPrepared statementと呼ばれています。

そのため、PostgreSQL → JDBCの順で勉強していると、

(JDBC APIの)PreparedStatementを使ってクエリを投げているのに(PostgreSQLの)Prepared Statement機能が使われていない( ;д;)...

というポルナレフ状態になります。

自分はこちらのハマり方をしました。。。

PostgreSQLのPrepared Statement機能もこれまた予想外の挙動をする時があってハマりやすいのですが、それはまた別途書きます。

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9