sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQLサーバー側のプリペアドステートメントの寿命はどれくらいですか

    つまり、あなたの質問は最終的に「java.sql.PreparedStatement」に要約されます。 最後に「これがサーバーで準備されたプランでどのように機能するか」に関する回答を参照してください。

    答えは次のとおりです。これは、使用するJDBCドライバーによって異なります。

    TL; DR :最新のドライバーでは、サーバーで準備されたステートメントは、接続が切断されるまで、またはステートメントが別のステートメントによって削除されるまで存続します(通常のLRU削除)。

    注:PostgreSQLサーバーはデータベース接続間でプリペアドステートメントを共有できないため、JDBCドライバーが実行できる最善の方法は、各接続でプランをキャッシュしておくことです。

    注:JDBC仕様では、?, ?の使用が義務付けられています バインドプレースホルダーの場合、サーバーは$1, $2を必要とします したがって、JDBCドライバーは、いわゆる解析済みSQLテキストもキャッシュします。

    よく知られているJDBCドライバーには、pgjdbcとpgjdbc-ngの2つがあります

    pgjdbc

    https://github.com/pgjdbc/pgjdbc

    pgjdbc9.4-1202 以降 PreparedStatementを使用すると、サーバー側のプランが自動的にキャッシュされます。 注:close()を実行しても、ステートメントはキャッシュされます。 PreparedStatement 。サーバー側の準備を行うには、クエリを5回実行する必要があります(prepareThresholdで構成できます)。 。

    現在、キャッシュは接続ごとに実装されています。デフォルトでは、pgjdbcは256をキャッシュします(preparedStatementCacheQueries )クエリおよび最大preparedStatementCacheSizeMiB クエリの。これは控えめな設定なので、調整することをお勧めします。 ドキュメント を参照してください。 プロパティの説明については、キャッシュには解析済みステートメントとサーバー準備済みステートメントの両方が含まれます。

    githubの問題: https://github.com/pgjdbc/pgjdbc/pull/319 >

    pgjdbc-ng

    https://github.com/impossibl/pgjdbc-ng

    私はpgjdbc-ngに興味がありませんが、両方の解析を行っているようです(デフォルトのキャッシュサイズは 250 クエリ)およびサーバー準備(デフォルトのキャッシュサイズは 50 クエリ)。サーバー側のプリペアドステートメントのサポートは2014年2月24日に開始されたため、少し新しいバージョンを使用すると、ステートメントのキャッシュを取得できます。

    注:誤って非常に長いクエリを使用した場合は、OutOfMemoryを押すことができます pgjdbc-ngは、保持されているバイト数に基づいてエントリを削除できないためです。

    キャッシュは接続ごとであるため、ステートメントを閉じても透過的に使用されます。

    pgjdbc-ngのパフォーマンスについてはあまり言えませんが、前回jmhをスローしようとして以来、ランダムな例外で失敗しました。

    githubの問題: https://github.com/impossibl/pgjdbc-ng/pull/ 69

    サーバーで準備された計画

    PostgreSQLにはPREPAREがあります およびDEALLOCATE EXECを送信するときにステートメントを参照するコマンド ワイヤー上。 2つのことを最適化します:

    1. PREPAREを使用する場合 dステートメント(つまり、サーバーで準備されたステートメント)の場合、クライアントはクエリテキストを何度も送信する必要はありません。短いクエリ名とバインド変数の値を送信するだけです。
    2. 9.2以降、データベースはクエリの最初の数回の実行を再計画しようとします。これは、クエリに複数のプランが必要な場合、または一般的なプランで十分かどうかを試すために行われます。最終的に(クエリにパラメータがない場合はすぐに)、データベース一般的なプランに切り替える可能性があります
    3. 12以降、サーバーで準備されたすべてのステートメントを汎用プランまたはカスタムプランで強制的に実行する設定があります。 plan_cache_mode =auto | force_custom_plan | force_generic_plan

    つまり、PreparedStatement JDBC側でのクエリ解析とデータベース側でのクエリプランニングの両方を最適化します。

    詳細はこちら: http://blog.endpoint .com / 2014/04 / custom-plans-prepared-statements-in.html

    PL/pgSQLで準備されたステートメント

    ドキュメントによると、PostgreSQL キャッシュ> PL/pgSQLで使用されるクエリの計画。これは数回の実行(正確なしきい値を覚えていません)の後に発生するため、ストアドプロシージャを作成した後は少し遅くなる可能性がありますが、キャッシュされたプランに切り替わります(データベースが汎用プランの使用に同意した場合)特定のクエリの場合)。

    つまり、「キャッシュされた実行プラン」を実現するには、最新のJDBCドライバーを使用するか、すべてのクエリをストアドプロシージャにラップする必要があります。プロシージャの呼び出しは実行ごとに再計画されますが、呼び出し自体は通常、プロシージャを構成するクエリよりもはるかに短いです。



    1. 注文後にOracleクエリによって返される行数を制限するにはどうすればよいですか?

    2. MySQLSUMIFフィールドb=フィールドa

    3. 変更データキャプチャまたは変更追跡-従来の監査証跡テーブルと同じですか?

    4. CloudFirestoreデータベースへのデータの追加