2011-02-11 16 views
3

我处于一个项目的中间,涉及试图从70GB的xml文档中获取大量信息并将其加载到关系数据库中(本例中为postgres)我目前使用python脚本和psycopg2来做到这一点插入和whatnot。我发现随着一些表中的行数增加。 (其中最大的是500万行左右)脚本的速度(插入)已经放慢了抓取速度。现在需要几分钟的时间大约需要一个小时。Postgres性能提示加载数十亿行

我能做些什么来加快速度?我在使用python和psycopg2来完成这项任务时错了吗?有什么我可以做的数据库,可以加快这个过程。我的感觉完全是错误的。

回答

0

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

如果是这样,也许你可以尝试提交一个较小的交易批量大小。把它分成更小的记录块(1K,10K,100K等),看看是否有帮助。

+1

PostgreSQL没有回滚日志。 – 2011-02-11 12:22:44

+0

PostgreSQL具有预写日志,与其他数据库中的回滚日志具有相同的用途。 – 2011-02-15 16:49:48

1

wal_buffers和checkpoint_segments的设置是什么?对于大型交易,你必须调整一些设置。检查manual

考虑一下PostgreSQL 9.0 High Performance这本书,还有很多要调整的数据库配置来获得高性能。

+1

将wal_buffers和checkpoint_segments设置得太低不会导致随着表大小增长而显着变差的问题。这可能会有所帮助,但可能无法解决缩放问题。感谢您的插件。 – 2011-02-15 17:06:01

1

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

0

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

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

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

如果你能负担得起重新创建或从头开始恢复您的数据库集群系统死机或断电,那么你可以用“F”选项,这将使OS写高速缓存开始的Postgres的情况。

0

有提示的关于这一主题的文档的Populating a Database部分名单。您也可以使用Tuning Your PostgreSQL Server中的提示加速一般性能。

检查外键的开销可能随着表大小的增加而增长,这会因为您一次加载单个记录而变得更糟。如果你正在加载数据的70GB的价值,这将是远远快负荷期间停止外键,再重新编译他们时,它的进口。如果您使用单个INSERT语句,则尤其如此。切换而不是复制是不是有保障的改善或者,由于在执行挂起的触发队列管理 - 问题出现在第一文档链接进行了讨论。

从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只。从这个转储将告诉你如何重新创建你现在的结构。

0

最初的5密耳排不算什么,插入物的差别不应该改变,它是100k或1密耳; 012-1-2个索引不会放慢速度(如果填充因子设置为70-90,考虑到每个主要输入是表的1/10)。

Python与PSYCOPG2相当快。 一个小技巧,你反刍使用数据库扩展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(谨慎更改此操作可能会导致数据库在发生突然断电或硬件崩溃时崩溃)

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

使用预处理语句进行插入,投下变量

你反刍尝试将数据插入到未记录表中暂时保持数据

是具有插入其中来自一个子查询,功能或该等条件或值一样?