Postgres性能提示加载数十亿行

时间:2011-02-11 12:11:46

标签: python database-design postgresql psycopg2

我正处于一个项目的中间,涉及尝试从70GB的xml文档中获取大量信息并将其加载到关系数据库中(在本例中为postgres)我目前正在使用python脚本和psycopg2来执行此操作插入等等。我发现随着一些表中的行数增加。 (其中最大的行数约为500万行)脚本(插入)的速度已经放慢了速度。曾经花了几分钟的时间现在需要大约一个小时。

我该怎么做才能加快速度?使用python和psycopg2执行此任务是错误的吗?我可以对数据库做些什么来加速这个过程。我完全以错误的方式感觉到这一点。

7 个答案:

答案 0 :(得分:1)

wal_buffers和checkpoint_segments有哪些设置?对于大型交易,您必须调整一些设置。查看manual

考虑一下这本书PostgreSQL 9.0 High Performance,除了数据库配置之外,还有更多内容需要调整才能获得高性能。

答案 1 :(得分:1)

考虑到这个过程在此之前是相当有效的,并且只是在数据集长大的时候,它减慢了我的猜测,它是索引。您可以尝试在导入之前删除表上的索引,并在完成后重新创建它们。这应该加快速度。

答案 2 :(得分:0)

我会查看回滚日志。如果你在一次交易中这样做,他们必须变得非常大。

如果是这种情况,也许您可​​以尝试提交较小的事务批量大小。将其分成较小的记录块(1K,10K,100K等),看看是否有帮助。

答案 3 :(得分:0)

我尝试使用COPY而不是插入。这就是备份工具用于快速加载的原因。

检查此表中的所有外键是否在目标表上都有相应的索引。或者更好 - 在复制之前暂时删除它们并在之后重新创建。

将checkpoint_segments从默认值3(这意味着3 * 16MB = 48MB)增加到更高的数字 - 例如尝试32(512MB)。确保你有足够的空间来存储这些额外的数据。

如果您能够在系统崩溃或电源故障的情况下从头开始重新创建或恢复数据库集群,那么您可以使用“-F”选项启动Postgres,这将启用操作系统写入缓存。

答案 4 :(得分:0)

答案 5 :(得分:0)

文档的Populating a Database部分提供了有关此主题的提示列表。您也可以使用Tuning Your PostgreSQL Server中的提示来加快一般性能。

随着表大小的增加,检查外键的开销可能会增加,这会因为您一次只加载一条记录而变得更糟。如果您正在加载70GB的数据,那么在加载期间删除外键会快得多,然后在导入时重建它们。如果您使用单个INSERT语句,则尤其如此。由于管理待处理的触发队列的方式,切换到COPY也不是保证改进 - 第一个文档链接中讨论的问题。

在psql提示符下,您可以找到强制执行外键的约束的名称,然后使用该名称删除它,如下所示:

\d tablename
ALTER TABLE tablename DROP CONSTRAINT constraint_name;

完成加载后,您可以使用以下内容将其恢复:

ALTER TABLE tablename ADD CONSTRAINT constraint_name FOREIGN KEY (other_table) REFERENCES other_table (join_column);

找出用于还原的确切语法的一个有用技巧是在数据库上执行 pgdump --schema-only 。从中转储将向您展示如何重新创建您现在拥有的结构。

答案 6 :(得分:0)

前5密耳行没什么,插入的差异不应该是100k或1 mil; 1-2指数不会减慢那么多(如果填充因子设置为70-90,考虑到每个主要导入是表的1/10)。

使用PSYCOPG2的python非常快。 一个小技巧,你使用数据库扩展XML2来读取/使用数据

小例子 https://dba.stackexchange.com/questions/8172/sql-to-read-xml-from-file-into-postgresql-database

duffymo是对的,尝试提交10000个插入块(仅在最后提交或在每个插入后非常昂贵) 如果你做了很多删除和更新,autovacuum可能会膨胀,你可以在某些表的开始时暂时关闭它。根据您的服务器可用资源设置work_mem和maintenance_work_mem ... 对于插入,增加wal_buffers,(9.0及更高版本的默认设置为自动-1)如果你使用的是版本8 postgresql,你应该手动增加它 cud还会关闭fsync并测试wal_sync_method(谨慎更改这可能会导致数据库崩溃,如果发生突然断电或硬件崩溃,则不安全)

尝试删除外键,禁用触发器或设置触发器不运行/跳过执行的条件;

使用预处理语句进行插入,转换变量

你试图将数据插入到一个未记录的表中以临时保存数据

是具有来自子查询,函数等的条件或值的插入吗?