插入PostgreSQL / PostGIS数据库太慢了

时间:2013-11-08 22:41:16

标签: perl postgresql twitter postgis

我正在开发一个项目,该项目要求我提供实时的Twitter Feed并将其中的记录存储在PostgreSQL数据库中。该项目要求存储推文的位置数据,以便在PostGIS下进行搜索。我正在使用perl脚本来获取Twitter提要(使用AnyEvent :: Twitter :: Stream和Twitter API)。每5000条推文,脚本fork()和子进程发出SQL以插入行。我正在使用AutoCommit => 0加速插入。

问题是子进程没有在下一个5000进入之前存储5000条推文,所以我得到了很多postgres进程。我需要弄清楚如何加快数据库插入速度以允许子进程在下一个进程启动之前退出。

子进程现在执行的任务(对于每条推文)是:

  • 在推文表中插入记录,使用ST_GeomFromEWKT将纬度/经度数据转换为GIS坐标
  • 确保推文的作者和推文中提到的任何用户都在用户表中
  • 在相关表格中插入用户和主题标签的提及

任何有关诊断速度或加快过程速度的建议都会对您有所帮助。这最终必须实时工作,因此临时表和文本文件不是很好的选择。该服务器是双Xeon HP服务器,运行带有8G RAM的Debian。

2 个答案:

答案 0 :(得分:4)

在postgres中,docs是通过滥用select子句中的insert来加速插入的注释。 这似乎是一个显着的差异,你试过吗?

  

更快的INSERT的有用提示:   您可以使用INSERT INTO tbl< query>通过将它们组合在一起来加快插入速度的语法。例如......

INSERT INTO my_table SELECT 1, 'a' UNION SELECT 2, 'b' UNION SELECT 3, 'c' UNION ...
  

如果为每个INSERT语句批量处理多组值,并为每个事务批量处理多个INSERT语句,则可以显着提高插入性能。我设法通过使用这种技术批量处理100(小)来在PostgreSQL 8.1 / Win2K安装上实现快8倍的插入。

否则,如果无法使postgres达到所需的速度,则可以在HP盒上检查IO性能。

另外,检查插入后是否有许多索引需要更新。也许你甚至需要告别许多约束(FK约束)。这将允许以任何顺序插入记录,并且在插入推文之前无需等待用户创建。

我还会检查,如果有可能在收集推文时检查数据库中的用户。 最后但同样重要的是,您应该实现一个队列来插入5000条推文的批次,而不是简单地将它们发送到数据库。

答案 1 :(得分:0)

I've benchmarked performance of creating pointsST_GeomFromEWKT是最慢的方法。尝试在预准备语句中使用ST_MakePoint以最小化任何开销:

use DBI;

# Prepare an insert
$sth=$dbh->prepare("INSERT INTO mytable (geom) ".
                   "SELECT ST_SetSRID(ST_MakePoint(?, ?), 4326) AS geom");

# In a for-loop of 5000 points, do the insert
$sth->execute($longitude, $latitude);