0

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

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

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

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

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

4

2 回答 2

4

在 postgres 文档中,有一条关于通过滥用 insert from select 子句来加速插入的评论。这似乎是一个显着的差异,你试过吗?

更快插入的有用提示:您可以使用 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 条推文的批次,而不是简单地将它们发送到数据库。

于 2013-11-08T23:00:31.897 回答
0

我已经对创建点的性能进行了基准测试,并且ST_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);
于 2013-11-12T00:44:52.903 回答