sql >> Databáze >  >> RDS >> PostgreSQL

Pochopení dávkových operací JDBC

Mohou to být různé druhy dávkování a já bych pokryl jeho část ovladače PostgreSQL JDBC (pgjdbc).

TL;DR:pgjdbc používá méně síťových roundripů v případě použití dávkového API. BatchedQuery se používá pouze v případě, že reWriteBatchedInserts=true je předán do nastavení připojení pgjdbc.

Můžete najít https://www.slideshare.net/VladimirSitnikv/postgresql-and-jdbc-striving-for-high-performance relevantní (snímek 44,...)

Pokud jde o provádění dotazu, latence sítě často tvoří významnou část uplynulého času.

Předpokládejme, že případ je vložit 10 řádků.

  1. Žádné dávkování (např. pouze PreparedStatement#execute ve smyčce). Ovladač provede následující

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

    Značný čas by se strávil v „čekání na DB“

  2. Dávkové API JDBC. To je PreparedStatement#addBatch() umožňuje ovladači odeslat více "spuštění dotazu" v rámci jediné sítě. Současná implementace by však stále rozdělovala velké dávky na menší, aby se zabránilo uváznutí TCP.

    Akce by byly mnohem lepší:

    execute query
    ...
    execute query
    execute query
    execute query
    sync <-- wait for the response from the DB
    
  3. Všimněte si, že i s #addBatch , je zde režie příkazů "provést dotaz". Zpracování každé zprávy jednotlivě trvá serveru značný čas.

    Jedním ze způsobů, jak snížit počet dotazů, je použití vkládání s více hodnotami. Například:

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

    Tento PostgreSQL umožňuje vkládat více řádků najednou. Nevýhodou je, že nemáte podrobnou (na řádek) chybovou zprávu. V současné době Hibernate neimplementuje vkládání více hodnot.

    Nicméně pgjdbc může od 9. 4. 1209 (2016-07-15) za běhu přepisovat běžné dávkové vložky do více hodnot.

    Chcete-li aktivovat přepis více hodnot, musíte přidat reWriteBatchedInserts=true vlastnost připojení. Tato funkce byla původně vyvinuta na https://github.com/pgjdbc/pgjdbc/pull/491

    K vložení 10 řádků je dost chytré použít 2 příkazy. První z nich je 8-hodnotový příkaz a druhý je 2-hodnotový příkaz. Využití mocnin dvou umožňuje pgjdbc udržovat počet různých příkazů rozumný, což zlepšuje výkon, protože často používané příkazy jsou připravovány serverem (viz Jaká je životnost příkazu připraveného na straně serveru PostgreSQL)

    BatchedQuery představuje tento druh příkazů s více hodnotami, takže tuto třídu uvidíte použitou v reWriteBatchedInserts=true pouze případ.

    Nevýhody této funkce mohou zahrnovat:nižší detaily jako "výsledek dávky". Například běžná dávka vám poskytne „počet řádků na výpis“, avšak v případě více hodnot získáte pouze stav „výpis dokončen“. Kromě toho může přepisovač za běhu selhat při analýze určitých příkazů SQL (např. https://github.com/pgjdbc/pgjdbc/issues/1045).



  1. Proč jsou v hodnotách sloupce IDENTITY mezery?

  2. Vybrat všechny sloupce kromě jednoho v MySQL?

  3. UnsatisfiedLinkError v nativní metodě

  4. Jak změníte kódování znaků postgresové databáze?