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

Изпълнение на последователности и сериали в Postgres-XL

В Postgres-XL последователностите се поддържат в Global Transaction Manager (GTM), за да се гарантира, че им се присвояват неконфликтни стойности, когато се увеличават от множество възли. Това добавя значителни допълнителни разходи за заявка, извършваща хиляди INSERT в таблица със серийна колона, увеличаване на последователността една по една и извършване на мрежово двупосочно пътуване до GTM за всяко INSERT.

Шон Томас в скорошен блог се оплака, че INSERT работят по-бавно на Postgres-XL в сравнение с ванилия PostgreSQL. Вече има начин за подобряване на производителността за последователности, но очевидно не е добре рекламиран. Мислех, че това е добра възможност да обясня съоръжението.

Postgres-XL предоставя настройваем от потребителя GUC, наречен sequence_range . Всеки бекенд изисква блок от стойности на последователността, контролирани от този GUC. Като се има предвид, че COPY се използва популярно за групово зареждане на данни в Postgres, Postgres-XL автоматично отменя този GUC по време на операция COPY и го задава на 1000, като по този начин драстично подобрява производителността на COPY. За съжаление, за обикновени INSERT, по подразбиране е 1 и освен ако потребителят не зададе изрично sequence_range до разумно по-висока стойност, производителността на INSERT страда. Ето един пример, използващ същата примерна схема, използвана от Шон в публикацията му в блога.

CREATE TABLE sensor_log (
  sensor_log_id  SERIAL PRIMARY KEY,
  location       VARCHAR NOT NULL,
  reading        BIGINT NOT NULL,
  reading_date   TIMESTAMP NOT NULL
) DISTRIBUTE BY HASH (sensor_log_id);

postgres=# \timing
Timing is on.
postgres=# INSERT INTO sensor_log (location, reading, reading_date)                                                                                                                         SELECT s.id % 1000, s.id % 100, now() - (s.id || 's')::INTERVAL                                                                                                                    FROM generate_series(1, 40000) s(id);
INSERT 0 40000
Time: 12067.911 ms

postgres=# set sequence_range TO 1000;
SET
Time: 1.231 ms
postgres=# INSERT INTO sensor_log (location, reading, reading_date)                                                                                                                         SELECT s.id % 1000, s.id % 100, now() - (s.id || 's')::INTERVAL                                                                                                                    FROM generate_series(1, 40000) s(id);
INSERT 0 40000
Time: 397.406 ms

Така че като зададете подходящо sequence_range до 1000, производителността на заявката INSERT се подобри почти 30 пъти.

Когато тази функция беше добавена, стойността по подразбиране на GUC за диапазон на последователност беше зададена на 1, защото може да остави дупки в стойностите на последователността. Но разглеждайки последиците от производителността за много често срещан случай на употреба, решихме да увеличим стойността по подразбиране до 1000 и това вече е ангажирано с клона XL9_5_STABLE на хранилището.

Важно е да се отбележи, че докато е висока стойност на sequence_range ще подобри производителността за последователности и сериали, може също да остави големи дупки в диапазони от последователности, тъй като диапазоните на последователности се кешират на ниво бекенд. За да се справи с този проблем, Postgres-XL започва с посочената стойност на параметъра CACHE, използвана по време на създаване на последователност, и я удвоява всеки път (ограничено от последователност_диапазон), ако последователностите се консумират с много висока скорост.

Подобно подобрение може да се постигне и чрез увеличаване на стойността на параметъра CACHE на последователността, така че част от стойностите на последователността да се кешират на ниво бекенд. Следващият пример показва как да направите това за серийна колона. Но диапазон_на последователност GUC предоставя лесен начин за отмяна на глобалното подразбиране и също така гарантира, че последователностите се кешират само когато се увеличават много бързо.

postgres=# ALTER SEQUENCE sensor_log_sensor_log_id_seq CACHE 1000;                                                                                                             ALTER SEQUENCE
Time: 8.683 ms
postgres=# SET sequence_range TO 1;
SET
Time: 2.341 ms
postgres=# INSERT INTO sensor_log (location, reading, reading_date)                                                                                                            SELECT s.id % 1000, s.id % 100, now() - (s.id || 's')::INTERVAL                                                                                                                  FROM generate_series(1, 40000) s(id);
INSERT 0 40000
Time: 418.068 ms

Можете да изберете някоя от тези техники, за да подобрите производителността. Въпреки че сега стойността по подразбиране на sequence_range се променя на 1000, не много потребители може да видят разликата в производителността.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да картографирате PostgreSQL масив с Hibernate

  2. Оптимизация на заявки в PostgreSQL. EXPLAIN Basics – Част 2

  3. Какво изисква този JavaScript?

  4. Настройка на PostgreSQL:Ключови неща за повишаване на производителността

  5. Какво точно обяснява PostgreSQL?