Высокоскоростная вставка одной строки с помощью PostgreSQL и TimescaleDB

У меня есть случай с TSDB Hypertable, который выглядит примерно так:

CREATE TABLE data (
  pool_id INTEGER NOT NULL,
  ts TIMESTAMP NOT NULL,
  noise_err DECIMAL,
  noise_val DECIMAL,
  signal_err DECIMAL,
  signal_val DECIMAL,
  high_val DECIMAL,
  low_val DECIMAL,

  CONSTRAINT data_pid_fk FOREIGN KEY (pool_id) REFERENCES pools (id) ON DELETE CASCADE
);

CREATE UNIQUE INDEX data_pts_idx ON data (pool_id, ts);
SELECT create_hypertable('data', 'ts', 'pool_id', 100);

Существует ~ 1000 пулов, data содержит ›минутные записи за 1 год для каждого пула и довольно много аналитических запросов, работающих с данными за последние 3-5 дней. Новые данные поступают с произвольной задержкой: от 10 мс до 30 с в зависимости от пула.

Теперь проблема: мне нужно выполнять аналитические запросы как можно быстрее после получения новой записи, поэтому я не могу вставлять их партиями, и мне нужно ускорить вставку одной строки.

Я запустил timescaledb-tune, затем отключил синхронные фиксации (synchronous_commit = off), поиграл с unlogged табличным режимом и попытался отключить автоматический вакуум, что не очень помогло. Лучшее время вставки, которое я получаю, составляет ~ 37 мс и ухудшается, когда количество одновременных вставок начинается до 110 мс.

Что еще, кроме удаления индексов / ограничений, я могу сделать для ускорения вставки одной строки?


person Daniel    schedule 12.11.2020    source источник
comment
Разделение пространства может снизить производительность. В чем причина использования разбиения на 100 разделов?   -  person k_rus    schedule 13.11.2020
comment
@a_horse_with_no_name Я использую PG версии 12.   -  person Daniel    schedule 13.11.2020
comment
@k_rus суть заключалась в том, чтобы сохранить как можно больше данных в ОЗУ, чтобы последняя неделя всех пулов всегда была в ОЗУ.   -  person Daniel    schedule 13.11.2020
comment
Используйте стандартные системные инструменты, чтобы увидеть, где находится узкое место. top, sar, vmstat. Также возьмите образец поля wait_event в pg_stat_activity.   -  person jjanes    schedule 14.11.2020


Ответы (2)


Во-первых, зачем вообще использовать шкалу времени для этой таблицы? Что вы получаете от этого, что стоит этого замедления?

Во-вторых, у вас есть 5200 разделов данных в год. Это приближается к неуправляемому количеству разделов.

person jjanes    schedule 13.11.2020
comment
В проекте уже используется PGSQL в качестве основной БД, и когда возникла необходимость хранить данные временных рядов, использовать TSDB было несложно. Без этого одиночные записи занимали до 1 секунды с одновременными записями. Смысл такого большого количества разделов состоял в том, чтобы сохранить последнюю неделю каждого пула в ОЗУ. - person Daniel; 13.11.2020
comment
1 с на вставку в один ряд - это гротеск. У вас есть несколько сотен индексов, о которых вы нам не рассказывали? - person jjanes; 14.11.2020
comment
@Daniel Смысл такого количества разделов состоял в том, чтобы сохранить последнюю неделю каждого пула в ОЗУ. Как в этом помогает разделение на pool_id? - person jjanes; 14.11.2020
comment
нет, таблица отображается как есть. Это началось, когда у меня было 10+ параллельных вставок - person Daniel; 14.11.2020
comment
Моя идея заключалась в том, что PG будет хранить столько, сколько может в ОЗУ, поэтому я нарезал столько данных. - person Daniel; 14.11.2020
comment
@Daniel Но последняя неделя - это последняя неделя, независимо от того, в каких еще измерениях вы ее тоже рубите. - person jjanes; 14.11.2020

Я сомневаюсь в необходимости аналитических запросов, которые должны видеть данные за последнюю долю секунды.

В любом случае, способ ускорить вставку одной строки:

  • Установите synchronous_commit на off.

    Но имейте в виду, что это означает потерю данных около полсекунды зафиксированных транзакций в случае сбоя! Если это неприемлемо, поиграйте с commit_siblings и commit_delay; это также уменьшит количество сбросов WAL.

  • Используйте подготовленные заявления. При использовании однорядных вставок время планирования будет значительным.

  • Не используйте незарегистрированные таблицы, если вы не возражаете, если вы потеряете данные после сбоя.

  • Не отключайте автоочистку.

  • Увеличьте max_wal_size, чтобы количество контрольных точек не превышало допустимого.

person Laurenz Albe    schedule 13.11.2020