Временные таблицы вздутие живота pg_attribute - PullRequest
0 голосов
/ 16 мая 2018

Я использую COPY для вставки больших объемов данных в нашу базу данных из CSV.Вставка выглядит примерно так:

-- This tmp table will contain all the items that we want to try to insert
CREATE TEMP TABLE tmp_items
(
    field1 INTEGER NULL,
    field2 INTEGER NULL,
    ...
) ON COMMIT DROP;

COPY tmp_items(
    field1,
    field2,
    ...
) FROM 'path\to\data.csv' WITH (FORMAT csv);

-- Start inserting some items
WITH newitems AS (
    INSERT INTO items (field1, field2)
    SELECT tmpi.field1, tmpi,field2
    FROM tmp_items tmpi
    WHERE some condition

    -- Return the new id and other fields to the next step
    RETURNING id AS newid, field1 AS field1
)
-- Insert the result into another temp table
INSERT INTO tmp_newitems SELECT * FROM newitems;

-- Use tmp_newitems to update other tables
etc....

Когда затем используются данные из tmp_items, чтобы выполнить несколько вставок в несколько таблиц.Мы проверяем наличие дубликатов и манипулируем данными несколькими способами перед вставкой, поэтому не все в tmp_items будет использовано или вставлено как есть.Мы делаем это с помощью комбинации CTE и более временных таблиц.

Это работает очень хорошо и достаточно быстро для наших нужд.Мы выполняем множество таких задач, и наша проблема в том, что pg_attribute становится очень раздутым, довольно быстро, а автовакуум, кажется, не в состоянии поддерживать скорость (и потребляет много процессора).

Мои вопросы:

  1. Можно ли выполнить вставку такого типа без использования временных таблиц?
  2. Если нет, нужно ли просто сделать автоочистку из pg_attribute большеагрессивный?Разве это не займет столько же или больше процессоров?

Ответы [ 2 ]

0 голосов
/ 08 апреля 2019

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

Таким образом, мы очень тяжело работаем с временными таблицами, имеющими> 500 об / мин и асинхронно выполняемыми через nodejs, и поэтому испытываем очень сильное вздутие pg_attribute из-за этого. Все, что вам осталось, - это очень агрессивная уборка, которая снижает производительность. Все ответы, приведенные здесь, не решают эту проблему, потому что удаление и воссоздание временной таблицы сильно раздувает pg_attribute, и поэтому в одно солнечное утро вы обнаружите, что производительность db мертва, а pg_attribute 200+ gb, в то время как ваш db будет выглядеть как 10gb.

Таким образом, решение элегантно это

create temp table if not exists my_temp_table (description) on commit delete rows;

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

не забудьте

vacuum full pg_depend;
vacuum full pg_attribute;

Приветствия:)

0 голосов
/ 16 мая 2018

Лучшим решением было бы создание временных таблиц в начале сеанса с

CREATE TEMPORARY TABLE ... (
   ...
) ON COMMIT DELETE ROWS;

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

Это уменьшит вздутие живота на pg_attribute, и вздутие живота не должно быть проблемой.

Вы также можете присоединиться к темной стороне (будьте осторожны, это не поддерживается):

  • Запустите PostgreSQL с помощью

    pg_ctl start -o -O
    

    , чтобы вы могли изменять системные каталоги.

  • Подключиться как суперпользователь и запустить

    UPDATE pg_catalog.pg_class
    SET reloptions = ARRAY['autovacuum_vacuum_cost_delay=0']
    WHERE oid = 'pg_catalog.pg_attribute'::regclass;
    

Теперь автоочистка будет работать гораздо агрессивнее на pg_attribute, и это, вероятно, решит вашу проблему.

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

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