pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
初次填充数据库时,可能需要插入大量数据。本节给出一些使这一过程尽可能高效的建议。
应关闭自动提交,只在最后提交一次。(在普通 SQL 中,这意味着开始时发出BEGIN,结束时发出COMMIT。某些客户端库可能会替调用方完成这件事,在这种情况下需要确认它们确实会在所需的时候这样做。)如果允许每次插入都单独提交,PostgreSQL就必须为每一行的加入执行大量额外工作。把所有插入都放在一个事务中的另一个好处是:如果其中某一行插入失败,那么此前插入的所有行都会被回滚,这样就不会留下部分装载的数据。
COPY #使用COPY在一条命令中装载所有记录,而不是使用一系列INSERT命令。COPY命令针对装载大量行做了优化;它不如INSERT灵活,但在大规模数据装载时开销显著更小。由于COPY是一条单独的命令,因此采用这种方法填充表时无须关闭自动提交。
如果不能使用COPY,那么用PREPARE创建一个预备INSERT语句,再按需多次执行EXECUTE也会有所帮助。这样可以避免重复解析和规划INSERT的开销。
请注意,在装载大量行时,使用COPY几乎总是比使用INSERT更快,即使已经使用了PREPARE,并把多次插入批量放入同一个事务中也是如此。
如果正在装载一个新创建的表,最快的方法是先创建表,用COPY批量装载数据,然后再创建该表所需的索引。在已有数据的表上创建索引,要比在每行装载时对索引做增量更新更快。
如果正在扩充一个现有的表,可以先删除索引、装载表数据、然后再重建索引。当然,在索引缺失期间,其他数据库用户的性能可能会下降。删除唯一索引之前也必须慎重,因为唯一约束提供的错误检查会在索引缺失期间丧失。
maintenance_work_mem #在装载大量数据时,临时增大maintenance_work_mem配置变量可以提升性能。这是因为从头创建 B-树索引时需要对表的现有内容排序。允许合并排序使用更多内存意味着需要的合并趟数更少。maintenance_work_mem的较大设置还可能加快外键约束的验证。
checkpoint_segments #临时增大checkpoint_segments配置变量,也可以让大规模数据装载更快。这是因为向PostgreSQL中装载大量数据可能导致检查点比平常更频繁地发生,而正常频率由checkpoint_timeout配置变量指定。每次发生检查点时,所有脏页都必须刷写到磁盘。通过在批量装载期间临时增大checkpoint_segments,可以减少所需的检查点次数。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。