Може да има различни видове пакетиране и бих покрил част от драйвера на PostgreSQL JDBC (pgjdbc).
TL;DR:pgjdbc използва по-малко мрежови roundrips в случай, че се използва пакетен API. 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
, има допълнителни разходи за команди "изпълни заявка". Обработката на всяко съобщение поотделно отнема значително време на сървъра.Един от начините за намаляване на броя на заявките е използването на вмъкване на много стойности. Например:
insert into tab(a,b,c) values (?,?,?), (?,?,?), ..., (?,?,?)
Този PostgreSQL дава възможност за вмъкване на няколко реда наведнъж. Недостатъкът е, че нямате подробно (на ред) съобщение за грешка. Понастоящем Hibernate не прилага вмъкване на много стойности.
Въпреки това pgjdbc може да пренаписва обикновени пакетни вмъквания в много стойности в движение от 9.4.1209 (2016-07-15).
За да активирате пренаписването на няколко стойности, трябва да добавите
reWriteBatchedInserts=true
свойство на свързване. Функцията първоначално е разработена в https://github.com/pgjdbc/pgjdbc/pull/491Достатъчно умно е да използвате 2 израза, за да вмъкнете 10 реда. Първият е 8-ценен израз, а вторият е 2-значен оператор. Използването на правомощия на две позволява на pgjdbc да поддържа броя на отделните изрази разумен и това подобрява производителността, тъй като често използваните изрази са подготвени от сървъра (вижте Какъв е срокът на живот на подготвен израз от страна на PostgreSQL)
BatchedQuery
представлява този вид многозначни изрази, така че ще видите този клас, използван вreWriteBatchedInserts=true
само случай.Недостатъците на функцията може да включват:по-ниски детайли като „партиден резултат“. Например, обикновената партида ви дава "на брой редове на изявление", но в случай с много стойности просто получавате статус "извлечение завършено". На всичкото отгоре, пренаписвателят в движение може да не успее да анализира определени SQL изрази (напр. https://github.com/pgjdbc/pgjdbc/issues/1045).