さまざまな種類のバッチ処理が含まれる可能性があり、その一部としてPostgreSQL JDBCドライバー(pgjdbc)について説明します。
TL; DR:バッチAPIが使用されている場合、pgjdbcはネットワークラウンドリップの使用量を減らします。 BatchedQuery
reWriteBatchedInserts=true
の場合にのみ使用されます pgjdbc接続設定に渡されます。
https://www.slideshare.net/VladimirSitnikv/postgresql-and-jdbc-striving-for-high-performance関連(スライド44、...)
クエリの実行に関しては、ネットワーク遅延が経過時間の重要な部分を占めることがよくあります。
10行を挿入する場合を想定します。
-
バッチ処理なし(例:
PreparedStatement#execute
のみ ループ内)。ドライバーは次のことを実行しますexecute query sync <-- wait for the response from the DB execute query sync <-- wait for the response from the DB execute query sync <-- wait for the response from the DB ...
「DBを待つ」ことにかなりの時間が費やされるでしょう
-
JDBCバッチAPI。つまり、
PreparedStatement#addBatch()
ドライバーが単一のネットワークラウンドトリップで複数の「クエリ実行」を送信できるようにします。ただし、現在の実装では、TCPデッドロックを回避するために、大きなバッチを小さなバッチに分割します。アクションははるかに優れています:
execute query ... execute query execute query execute query sync <-- wait for the response from the DB
-
#addBatch
でも注意してください 、「クエリの実行」コマンドのオーバーヘッドがあります。各メッセージを個別に処理するには、サーバーにかなりの時間がかかります。クエリの数を減らす方法の1つは、複数値の挿入を使用することです。例:
insert into tab(a,b,c) values (?,?,?), (?,?,?), ..., (?,?,?)
このPostgreSQLでは、一度に複数の行を挿入できます。欠点は、詳細な(行ごとの)エラーメッセージがないことです。現在、Hibernateは複数値の挿入を実装していません。
ただし、pgjdbcは、9.4.1209(2016-07-15)以降、通常のバッチ挿入をオンザフライで複数値に書き換えることができます。
複数値の書き換えを有効にするには、
で開発されました。reWriteBatchedInserts=true
を追加する必要があります 接続プロパティ。この機能は当初、https://github.com/pgjdbc/pgjdbc/pull/49110行を挿入するために2つのステートメントを使用するのは十分に賢いです。最初のステートメントは8値のステートメントで、2番目のステートメントは2値のステートメントです。 2の累乗を使用すると、pgjdbcは個別のステートメントの数を正常に保つことができ、頻繁に使用されるステートメントがサーバーで準備されるため、パフォーマンスが向上します(PostgreSQLサーバー側で準備されたステートメントの寿命を参照)
BatchedQuery
はそのような複数値のステートメントを表しているため、reWriteBatchedInserts=true
で使用されているクラスが表示されます。 ケースのみ。この機能の欠点には、次のようなものがあります。「バッチ結果」としての詳細が低い。たとえば、通常のバッチでは「ステートメントごとの行数」が得られますが、複数の値の場合は「ステートメントが完了しました」というステータスになります。その上、オンザフライのリライターは特定のSQLステートメントの解析に失敗する可能性があります(例:https://github.com/pgjdbc/pgjdbc/issues/1045)。