sql >> Database >  >> RDS >> PostgreSQL

JDBC-batchbewerkingen begrijpen

Er kunnen verschillende soorten batchverwerking bij betrokken zijn, en ik zou er een deel van het PostgreSQL JDBC-stuurprogramma (pgjdbc) van maken.

TL;DR:pgjdbc gebruikt minder netwerk-roundrips voor het geval er batch-API wordt gebruikt. BatchedQuery wordt alleen gebruikt als reWriteBatchedInserts=true wordt doorgegeven aan de pgjdbc-verbindingsinstellingen.

Mogelijk vindt u https://www.slideshare.net/VladimirSitnikv/postgresql-and-jdbc-streving-for-high-performance relevant (dia 44,...)

Als het gaat om het uitvoeren van query's, is de netwerklatentie vaak een aanzienlijk deel van de verstreken tijd.

Stel dat het geval is om 10 rijen in te voegen.

  1. Geen batchverwerking (bijv. gewoon PreparedStatement#execute in een lus). De bestuurder zou het volgende doen

    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
    ...
    

    Opmerkelijke tijd zou worden doorgebracht in het "wachten op de DB"

  2. JDBC batch-API. Dat is PreparedStatement#addBatch() stelt de bestuurder in staat om meerdere "query-uitvoeringen" te verzenden in een enkele netwerkrondreis. De huidige implementatie zou echter nog steeds grote batches opsplitsen in kleinere om een ​​TCP-impasse te voorkomen.

    De acties zouden veel beter zijn:

    execute query
    ...
    execute query
    execute query
    execute query
    sync <-- wait for the response from the DB
    
  3. Merk op dat zelfs met #addBatch , is er overhead van "execute query"-opdrachten. Het kost de server veel tijd om elk bericht afzonderlijk te verwerken.

    Een van de manieren om het aantal zoekopdrachten te verminderen, is door het invoegen van meerdere waarden te gebruiken. Bijvoorbeeld:

    insert into tab(a,b,c) values (?,?,?), (?,?,?), ..., (?,?,?)
    

    Deze PostgreSQL maakt het mogelijk om meerdere rijen tegelijk in te voegen. Het nadeel is dat u geen gedetailleerde (per-rij) foutmelding krijgt. Momenteel implementeert Hibernate geen invoeging met meerdere waarden.

    Sinds 9.4.1209 (2016-07-15) kan pgjdbc echter reguliere batch-inserts on-the-fly herschrijven in multi-waarden.

    Om herschrijven met meerdere waarden te activeren, moet u reWriteBatchedInserts=true toevoegen verbinding eigendom. De functie is oorspronkelijk ontwikkeld in https://github.com/pgjdbc/pgjdbc/pull/491

    Het is slim genoeg om 2 statements te gebruiken om 10 rijen in te voegen. De eerste is een verklaring met 8 waarden en de tweede is een verklaring met twee waarden. Het gebruik van bevoegdheden van twee stelt pgjdbc in staat om het aantal afzonderlijke instructies gezond te houden, en dat verbetert de prestaties omdat vaak gebruikte instructies op de server zijn voorbereid (zie Wat is de levensduur van een PostgreSQL-opdracht aan de serverzijde)

    BatchedQuery vertegenwoordigt dat soort meerwaardige instructies, dus je zult zien dat die klasse wordt gebruikt in reWriteBatchedInserts=true alleen geval.

    De nadelen van de functie kunnen zijn:lagere details als het "batchresultaat". Bijvoorbeeld, reguliere batch geeft u "per statement rowcount", maar in het geval van meerdere waarden krijgt u gewoon de status "statement voltooid". Bovendien kan on-the-fly rewritter bepaalde SQL-statements mogelijk niet parseren (bijv. https://github.com/pgjdbc/pgjdbc/issues/1045 ).



  1. Profielen maken in Oracle voor gebruikersbeveiliging

  2. slechte Hibernate select-prestaties vergeleken met direct uitvoeren - hoe debuggen?

  3. SQL Union – Een uitgebreide gids over de UNION-operator

  4. TSQL:Hoe kan ik lokale tijd naar UTC converteren? (SQL-server 2008)