↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1
历史版本PostgreSQL 8.1 已于 2010 年 11 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

13.4. 填充一个数据库 #

初次填充数据库时,可能需要插入大量数据。本节给出一些使这一过程尽可能高效的建议。

13.4.1. 禁用自动提交 #

应关闭自动提交,只在最后提交一次。(在普通 SQL 中,这意味着开始时发出BEGIN,结束时发出COMMIT。某些客户端库可能会替调用方完成这件事,在这种情况下需要确认它们确实会在所需的时候这样做。)如果允许每次插入都单独提交,PostgreSQL就必须为每一行的加入执行大量额外工作。把所有插入都放在一个事务中的另一个好处是:如果其中某一行插入失败,那么此前插入的所有行都会被回滚,这样就不会留下部分装载的数据。

13.4.2. 使用COPY #

使用COPY在一条命令中装载所有记录,而不是使用一系列INSERT命令。COPY命令针对装载大量行做了优化;它不如INSERT灵活,但在大规模数据装载时开销显著更小。由于COPY是一条单独的命令,因此采用这种方法填充表时无须关闭自动提交。

如果不能使用COPY,那么用PREPARE创建一个预备INSERT语句,再按需多次执行EXECUTE也会有所帮助。这样可以避免重复解析和规划INSERT的开销。

请注意,在装载大量行时,使用COPY几乎总是比使用INSERT更快,即使已经使用了PREPARE,并把多次插入批量放入同一个事务中也是如此。

13.4.3. 移除索引 #

如果正在装载一个新创建的表,最快的方法是先创建表,用COPY批量装载数据,然后再创建该表所需的索引。在已有数据的表上创建索引,要比在每行装载时对索引做增量更新更快。

如果正在向现有表加入大量数据,那么删除索引、装载数据、再重建索引可能是更好的方案。当然,在索引缺失期间,其他数据库用户的性能可能会下降。删除唯一索引之前也必须慎重,因为唯一约束提供的错误检查会在索引缺失期间丧失。

13.4.4. 移除外键约束 #

与索引类似,“批量”检查外键约束比逐行检查更高效。因此,先删除外键约束、装载数据、再重建约束可能很有用。同样,这里也需要在装载速度与约束缺失期间失去错误检查之间做权衡。

13.4.5. 增加maintenance_work_mem #

在装载大量数据时,临时增大maintenance_work_mem配置变量可以提升性能。这个参数也有助于加速CREATE INDEX和ALTER TABLE ADD FOREIGN KEY命令。它对COPY本身帮助不大,因此这个建议只有在采用前述一种或两种技巧时才有意义。

13.4.6. 增加checkpoint_segments #

临时增大checkpoint_segments配置变量,也可以让大规模数据装载更快。这是因为向PostgreSQL中装载大量数据,会导致检查点比平常更频繁地发生,而正常频率由checkpoint_timeout配置变量指定。每次发生检查点时,所有脏页都必须刷写到磁盘。通过在批量装载期间临时增大checkpoint_segments,可以减少所需的检查点次数。

13.4.7. 事后运行ANALYZE #

每当显著改变了表中数据的分布,都强烈建议运行ANALYZE。这也包括向表中批量装载大量数据。运行ANALYZE(或VACUUM ANALYZE)可以确保规划器掌握该表的最新统计信息。如果没有统计信息,或者统计信息已经过时,规划器在生成查询计划时就可能做出糟糕决定,从而导致相关表性能不佳。

13.4.8. 关于pg_dump的一些注记 #

由pg_dump生成的转储脚本会自动应用上面若干条指导原则,但并非全部。 若要尽可能快速地还原pg_dump的转储,仍需手动做一些额外操作。 (注意,这些要点适用于还原转储,而不是创建转储。 在使用pg_restore从pg_dump归档文件加载时,相关要点是一样的。)

默认情况下,pg_dump使用COPY;而当它生成完整的模式加数据转储时,也会小心地先装载数据,再创建索引和外键。因此在这种情况下,上述若干指导原则已经被自动处理。剩下需要做的,只是在载入转储脚本之前为maintenance_work_mem和checkpoint_segments设置适当的(即比正常值大的)值,然后在完成后运行ANALYZE。

仅包含数据的转储仍然会使用COPY,但它不会删除或重建索引,通常也不会处理外键。 [8] 因此,在装载纯数据转储时,如果想采用这些技术,就需要自行负责删除并重建索引与外键。装载数据期间增大checkpoint_segments仍然有益,但没有必要同时增大maintenance_work_mem;后者更适合留到之后手工重建索引和外键时再调大。完成后也别忘了执行ANALYZE。



[8] 可以通过使用-X disable-triggers选项达到禁用外键的效果 — 但要注意,这样做是取消外键验证,而不仅仅是推迟它。因此如果使用该选项,就有可能插入坏数据。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。