Joe*_*oel 5 postgresql postgresql-9.6
我正在使用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....
Run Code Online (Sandbox Code Playgroud)
然后什么时候使用数据 tmp_items在多个表进行多次插入。我们在插入之前检查重复项并以几种方式操作数据,因此并非所有内容都tmp_items将按原样使用或插入。我们通过组合 CTE 和更多临时表来做到这一点。
这非常有效,并且速度足以满足我们的需求。我们做了很多这些,我们遇到的问题是pg_attribute是变得非常臃肿,而且 autovacuum 似乎无法跟上(并消耗大量CPU)。
我的问题是:
pg_attribute更具侵略性?这不会占用更多或更多的CPU吗?最好的解决方案是在会话开始时创建临时表
CREATE TEMPORARY TABLE ... (
...
) ON COMMIT DELETE ROWS;
Run Code Online (Sandbox Code Playgroud)
然后临时表将在会话期间保留,但在每次提交时清空。
这将减少pg_attribute可观的膨胀,并且膨胀应该不再是问题。
你也可以加入黑暗面(请注意,这是不受支持的):
使用以下命令启动 PostgreSQL
pg_ctl start -o -O
Run Code Online (Sandbox Code Playgroud)
以便您可以修改系统目录。
以超级用户身份连接并运行
UPDATE pg_catalog.pg_class
SET reloptions = ARRAY['autovacuum_vacuum_cost_delay=0']
WHERE oid = 'pg_catalog.pg_attribute'::regclass;
Run Code Online (Sandbox Code Playgroud)现在 autovacuum 将在 上更积极地运行pg_attribute,这可能会解决您的问题。
请注意,该设置将在重大升级后消失。
| 归档时间: |
|
| 查看次数: |
1745 次 |
| 最近记录: |