Det kan vara olika typer av batchning inblandade, och jag skulle täcka PostgreSQL JDBC-drivrutinen (pgjdbc) en del av det.
TL;DR:pgjdbc använder färre nätverksrundor om batch-API används. BatchedQuery
används endast om reWriteBatchedInserts=true
skickas till pgjdbc-anslutningsinställningarna.
Du kanske finner https://www.slideshare.net/VladimirSitnikv/postgresql-and-jdbc-striving-for-high-performance relevant (bild 44,...)
När det gäller exekvering av frågor är nätverkslatens ofta en betydande del av den förflutna tiden.
Anta att fallet är att infoga 10 rader.
-
Ingen batchning (t.ex. bara
PreparedStatement#execute
i en slinga). Föraren skulle utföra följandeexecute 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 ...
Anmärkningsvärd tid skulle spenderas i "väntar på DB"
-
JDBC batch API. Det är
PreparedStatement#addBatch()
gör det möjligt för föraren att skicka flera "frågekörningar" i en enda nätverksresa. Nuvarande implementering skulle dock fortfarande dela upp stora partier i mindre för att undvika TCP-dödläge.Åtgärderna skulle vara mycket bättre:
execute query ... execute query execute query execute query sync <-- wait for the response from the DB
-
Observera att även med
#addBatch
, det finns overhead av "exekveringsfråga"-kommandon. Det tar servern anmärkningsvärd tid att behandla varje meddelande individuellt.Ett av sätten att minska antalet frågor är att använda multi-values insert. Till exempel:
insert into tab(a,b,c) values (?,?,?), (?,?,?), ..., (?,?,?)
Denna PostgreSQL gör det möjligt att infoga flera rader samtidigt. Nackdelen är att du inte har ett detaljerat (per rad) felmeddelande. För närvarande implementerar Hibernate inte infogning av flera värden.
Men pgjdbc kan skriva om vanliga batch-inlägg till flervärden i farten sedan 9.4.1209 (2016-07-15).
För att aktivera omskrivning av flera värden måste du lägga till
reWriteBatchedInserts=true
anslutningsegendom. Funktionen utvecklades ursprungligen på https://github.com/pgjdbc/pgjdbc/pull/491Det är smart nog att använda 2 satser för att infoga 10 rader. Det första är ett påstående med 8 värden, och det andra är ett påstående med två värden. Användning av tvåstyrkorna gör det möjligt för pgjdbc att hålla antalet distinkta uttalanden sunda, och det förbättrar prestandan eftersom ofta använda satser är serverförberedda (se Vad är livslängden för en PostgreSQL-serversida förberedd sats )
BatchedQuery
representerar den typen av multi-valued statements, så du kommer att se den klassen som används ireWriteBatchedInserts=true
endast fall.Nackdelarna med funktionen kan inkludera:lägre detaljer som "batchresultat". Till exempel ger vanlig batch dig "per uttalande radantal", men i fall med flera värden får du bara statusen "uttalandet avslutat". Utöver det kan det hända att omskrivaren i farten misslyckas med att analysera vissa SQL-satser (t.ex. https://github.com/pgjdbc/pgjdbc/issues/1045 ).