Perl PostgreSQL在太多插入上阻塞

Perl PostgreSQL在太多插入上阻塞,perl,postgresql,twitter,insert,Perl,Postgresql,Twitter,Insert,我正在一个研究平台上工作,该平台通过Twitter API读取相关的Twitter提要,并将其存储在PostgreSQL数据库中,以供将来分析。中间件是Perl,服务器是运行Debian linux的8GB RAM的HP ML310 问题是twitter提要可能相当大(每秒有许多条目),我无法在返回等待下一条tweet之前等待插入。因此,我所做的是使用fork(),使每条tweet都有一个新的进程插入到数据库和侦听器中,并快速返回以获取下一条tweet。然而,由于这些过程中的每一个都有效地打开了

我正在一个研究平台上工作,该平台通过Twitter API读取相关的Twitter提要,并将其存储在PostgreSQL数据库中,以供将来分析。中间件是Perl,服务器是运行Debian linux的8GB RAM的HP ML310

问题是twitter提要可能相当大(每秒有许多条目),我无法在返回等待下一条tweet之前等待插入。因此,我所做的是使用fork(),使每条tweet都有一个新的进程插入到数据库和侦听器中,并快速返回以获取下一条tweet。然而,由于这些过程中的每一个都有效地打开了一个到PostgreSQL后端的新连接,因此系统永远赶不上它的twitter提要


我愿意使用连接池的建议和/或升级硬件,如果有必要,使这项工作,但将感谢任何建议。这可能是RAM受限,还是有配置或软件方法可以让系统足够快?

如果您为每个插入打开和关闭一个新连接,这将对您造成很大的伤害。您应该使用连接池。创建新的数据库连接不是一件轻量级的事情

为每个插入执行一个fork()可能也不是一个好主意。你不能创建一个进程来简单地处理插入和监听套接字,或者扫描一个目录或类似的东西,然后创建另一个进程来通知插入进程(一个经典的生产者/消费者模式)。或者使用某种消息队列(我不知道Perl,所以我不能说那里有什么可用的工具)

在执行大容量插入时,在单个事务中执行这些操作,并在最后发送提交。不要提交每个插入。另一种选择是将行写入文本文件,然后使用
COPY
将它们插入数据库(不会比这更快)

您还可以稍微调整一下PostgreSQL服务器。如果您能够承受在系统崩溃时丢失一些事务,那么您可能需要关闭
synchronous\u commit

如果您可以随时从头开始重建表(例如,通过重新插入tweets),您可能还希望将该表设置为“未标记”表。它的写入速度比常规表快,但如果Postgres没有清晰地显示出来,则会丢失表中的所有数据。

使用COPY命令。 一个脚本读取Tweeter并将字符串附加到磁盘上的CSV文件。
其他脚本在磁盘上查找CSV文件,重命名此文件并从此文件启动命令。

您可以在包中收集数据并使用balk insert。它更快。另外,检查不必要的索引。它可以减缓插入操作。您可以尝试删除除主群集索引之外的所有索引,稍后再处理数据。正如@user1883592所说,大容量插入通常更快,如果您不需要立即使用数据,您可能可以将传入的数据转储到一个平面文件中,然后执行一个大事务,以每X分钟插入X分钟的数据。我尝试过使用批量插入,例如,在累积100或500条tweet后使用fork()并生成一个一次批量插入所有tweet的进程。不幸的是,插入速度仍然很慢,以至于子进程堆积起来。我会尝试平面文件的方法。你能举一个插入查询的例子吗?