优化PostgreSQL中的批量更新性能
在Ubuntu 12.04上使用PG 9.1.
我们目前需要24小时才能运行大量UPDATE UPDATE table SET field1 = constant1,field2 = constant2,... WHERE id = constid (我们只是覆盖由ID标识的对象的字段.)值来自外部数据源(不在表中的DB中). 这些表每个都有一些索引,没有外键约束. 导入整个数据库的pg_dump需要2小时.这似乎是一个 生成一个以某种方式重建数据集的自定义程序 一些想法: >之后放弃所有非ID指数并重建? 基本上有很多东西要尝试,我们不确定是什么 我确实在表上有并发加载,但它是只读的.
假设
由于Q中缺少信息,我将假设: >您的数据来自数据库服务器上的文件. > Best way to populate a new column in a large table? >除索引外,根本没有依赖对象. 解 我建议你采用link from your third bullet中概述的类似方法.进行主要优化. 要创建临时表,有一种更简单,更快捷的方法: CREATE TEMP TABLE tmp_tbl AS SELECT * FROM tbl LIMIT 0; 来自数据库内的临时表的单个大UPDATE将比来自数据库外部的单个更新快几个数量级. 在PostgreSQL’s MVCC model中,UPDATE表示创建新行版本并将旧版本标记为已删除.这与INSERT和DELETE的组合价格一样高.另外,它会留下很多死元组.由于您无论如何都在更新整个表,因此创建一个新表并删除旧表会更快. 如果有足够的可用RAM,请将 要估计需要多少RAM,请使用小样本运行测试并使用db object size functions: SELECT pg_size_pretty(pg_relation_size('tmp_tbl')); -- complete size of table SELECT pg_column_size(t) FROM tmp_tbl t LIMIT 10; -- size of sample rows 完整的脚本 SET temp_buffers = '1GB'; -- example value CREATE TEMP TABLE tmp_tbl AS SELECT * FROM tbl LIMIT 0; COPY tmp_tbl FROM '/absolute/path/to/file'; CREATE TABLE tbl_new AS SELECT t.col1,t.col2,u.field1,u.field2 FROM tbl t JOIN tmp_tbl u USING (id); -- Create indexes like in original table ALTER TABLE tbl_new ADD PRIMARY KEY ...; CREATE INDEX ... ON tbl_new (...); CREATE INDEX ... ON tbl_new (...); -- exclusive lock on tbl for a very brief time window! DROP TABLE tbl; ALTER TABLE tbl_new RENAME TO tbl; DROP TABLE tmp_tbl; -- will also be dropped at end of session automatically 并发负载 表格上的并发操作(我在开始时的假设中排除)将等待,一旦表格被锁定在接近结束并且一旦提交事务就失败,因为表格名称立即被解析为其OID,但是新表具有不同的OID.该表保持一致,但并发操作可能会出现异常并且必须重复.这个相关答案的细节: > Best way to populate a new column in a large table? 更新路线 如果您(必须)转到UPDATE路由,请删除更新期间不需要的任何索引,然后重新创建它.创建一个索引要比为每个行更新它要便宜得多.这也可以允许HOT updates. 我在this closely related answer on SO中使用UPDATE概述了类似的过程. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |