Команда PostgreSQL CREATE TABLE AS создает ошибку OUT OF MEMORY - PullRequest
1 голос
/ 08 мая 2019

Я хочу сделать запрос к таблице размером 70 ГБ в PostgreSQL + TimeScaleDB и скопировать результат в другую таблицу.Проблема в том, что похоже, что Postgres пытается построить новую таблицу в памяти перед тем, как записать ее на диск, что, очевидно, вызывает ошибку OUT OF MEMORY.

Таблица, которую я хочу скопировать, содержит данные временных рядов ссекунда точности.Я хочу создать копии этой таблицы с меньшей точностью, чтобы быстрее выполнять запросы на больших временных интервалах - где такая точность не нужна.Когда я делаю это для точности 1 недели, 1 дня или 1 часа, это работает.Проблема возникает только с точностью до 1 минуты.

Я использую запрос для создания новой таблицы:

CREATE TABLE downsampling_1m AS
SELECT time_bucket('1 minute', time) AS one_minute_bucket, name, avg(value) AS avg_value,
min(value) AS min_value, max(value) AS value, stddev(value) AS stddev_value
FROM original_table
GROUP BY name, one_minute_bucket
ORDER BY one_minute_bucket;

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

1 Ответ

0 голосов
/ 13 мая 2019

Я понял это, поэтому выкладываю ответ на случай, если кому-то понадобится это в будущем. TimeScale работает с так называемыми Hypertables, которые представляют собой набор таблиц, называемых чанками, каждая из которых соответствует определенному диапазону времени. Для пользователя эта коллекция таблиц рассматривается как единая таблица Hypertable. Таким образом, когда пользователь отправляет запрос по определенному диапазону данных, запрашиваются только фрагменты, соответствующие этому диапазону данных. Это один из приемов, используемых TimeScale, чтобы Postgres мог обрабатывать временные ряды.

Дело в том, что когда пользователь запрашивает весь Hypertable, все куски запрашиваются один за другим. Таким образом, в случае копии, если порция больше основной памяти, это вызовет ошибку.

Решение заключается в определении размера чанка при создании гипертаблицы:

SELECT create_hypertable('tableName', 'timeColumn', chunk_time_interval=interval);

С кусками, меньшими, чем размер основной памяти, это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...