PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Разбиране на JDBC пакетни операции

Може да има различни видове пакетиране и бих покрил част от драйвера на 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 реда.

  1. Без групиране (например просто 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"

  2. JDBC пакетен API. Това е PreparedStatement#addBatch() позволява на драйвера да изпраща множество "изпълнения на заявка" в една мрежа за двупосочно пътуване. Текущата реализация обаче все пак ще раздели големите партиди на по-малки, за да се избегне блокиране на TCP.

    Действията биха били много по-добри:

    execute query
    ...
    execute query
    execute query
    execute query
    sync <-- wait for the response from the DB
    
  3. Имайте предвид, че дори с #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).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Функцията low() за международни знаци в postgresql

  2. Как да направя големи неблокиращи актуализации в PostgreSQL?

  3. Как да разделяте транзакции само за четене и за четене-запис с JPA и Hibernate

  4. Въведение в PostgreSQL

  5. Получаване на неизвестен първичен ключ за таблица, докато идентификаторът е там