Я использую 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
очень быстро раздувается, а автоочистка, похоже, не справляется (и потребляет много ресурсов ЦП).
Мои вопросы:
- Можно ли выполнить такую вставку без использования временных таблиц?
- Если нет, то должны ли мы просто сделать автоочистку
pg_attribute
более агрессивной? Не будет ли это занимать столько же или больше ресурсов процессора?
pg_attribute
), потому что некоторые потерянные логические слоты все еще нуждались в них. - person Nick Barnes   schedule 16.05.2018VACUUM FULL
избавиться от мертвых строк. Просто кажется, что автопылесос их всех не удалит - person Joel   schedule 16.05.2018FROM STDIN (FORMAT BINARY)
, а также из CSV, так что я думаю, что в этом случае это не сработает? - person Joel   schedule 16.05.2018