咱们第一次填充数据库时可能须要作大量的表插入。 下面是一些建议,能够尽量高效地处理这些事情。php
关闭自动提交,而且只在每次(数据拷贝)结束的时候作一次提交。 (在纯 SQL 里,这就意味着在开始的时候发出 BEGIN, 而且在结束的时候执行 COMMIT。有些客户端的库可能背着你干这些事情, 这种状况下你必须确信只有在你要那些库干这些事情的时候它才作。) 若是你容许每一个插入都独立地提交,那么 PostgreSQL 会为所增长的每行记录作大量的处理。 在一个事务里完成全部插入的动做的最大的好处就是,若是有一条记录插入失败, 那么,到该点为止的全部已插入记录都将被回滚,这样你就不会很难受地面对一个只装载了一部分数据的表。html
使用 COPY 在一条命令里装载全部记录, 而不是一连串的INSERT命令。COPY 命令是为装载数量巨大的数据行优化过的; 它没 INSERT 那么灵活,可是在大量装载数据的状况下,致使的过荷也少不少。 由于 COPY 是单条命令,所以填充表的时候就没有必要关闭自动提交了。sql
若是你不能使用 COPY,那么 使用 PREPARE 来建立一个准备好的 INSERT, 而后使用 EXECUTE 屡次效率更高。 这样就避免了重复分析和规划 INSERT 的开销。数据库
请注意,在装载大量数据行的时候,COPY 几乎老是比 INSERT 快, 即便使用了 PREPARE 而且把多个 INSERT 命令绑在一个事务中也是这样的。性能
若是你正在装载一个新建立的表,最快的方法是建立表, 用COPY批量装载,而后建立表须要的任何索引。 在已存在数据的表上建立索引要比递增地更新所装载的每一行记录要快。优化
若是你对现有表增长大量的数据,可能先删除索引,装载表,而后从新建立索引更快些。 固然,在缺乏索引的期间,其余数据库用户的数据库性能将有负面的影响。 而且咱们在删除惟一索引以前还须要仔细考虑清楚,由于惟一约束 提供的错误检查在缺乏索引的时候会消失.spa
和索引同样,"批量地"检查外键约束比一行行检查更高效。 所以,也许咱们先删除外键约束,装载数据,而后重建约束会更高效。 一样,装载数据和缺乏约束而失去错误检查之间也有一个平衡。rest
在装载大量的数据的时候,临时增大 maintenance_work_mem 配置变量能够改进性能。 这个参数也能够帮助加速 CREATE INDEX 命令和 ALTER TABLE ADD FOREIGN KEY 命令。它不会对 COPY 自己有多大做用,因此这个建议只有在你使用上面的两个技巧中的一个或两个才有效。orm
临时增大 checkpoint_segments 配置变量也可让大量数据装载得更快。 这是由于向 PostgreSQL 里面装载大量的数据能够致使检查点操做 (由配置变量 checkpoint_timeout 声明) 比日常更加频繁发生。在发生一个检查点的时候,全部脏数据都必须刷新到磁盘上。 经过在大量数据装载的时候临时增长 checkpoint_segments, 所要求的检查点的数目能够减小。htm
无论甚么时候,若是你在增长或者更新了大量数据以后, 运行 ANALYZE 都是个好习惯。 运行 ANALYZE(或者 VACUUM ANALYZE) 能够保证规划器有最新的表的数据的统计。 若是没有统计数据或者统计数据太陈旧,那么规划器可能选择不好劲的查询规划,致使检索你的表的查询性能的恶化。
pg_dump 生成的转储脚本自动使用上面的若干个技巧, 但不是所有。要尽量快地装载 pg_dump 转储, 咱们须要手工作几个事情。(请注意,这些要点适用于恢复一个转储, 而不是建立一个转储的时候。一样的要点也适用于使用 pg_restore 从 pg_dump 归档文件装载数据的时候。)
缺省的时候,pg_dump 使用 COPY, 在它生成一个完整的模式和数据的转储的时候,它会很当心地先装载数据,而后建立索引和外键。 所以,在这个状况下,头几条技巧是自动处理的。你须要作的只是在装载转储脚本以前设置合适的(也就是说,比正常情况要大的) maintenance_work_mem 值和 checkpoint_segments 值, 而后在装载完成以后运行 ANALYZE。
只保存数据的转储仍然会使用 COPY,可是它不会删除或者重建索引, 而且它不会自动修改外键。 [1] 所以,在装载只有数据的转储的时候,是否使用删除以及重建索引和外键等技巧彻底取决于你。 装载数据的时候,增大 checkpoint_segments 仍然是有用的, 可是增大 maintenance_work_mem 就没什么必要了; 你只是应该在过后手工建立索引和外键的过后增大它。