2

我正在使用高速数据流并执行以下步骤将数据存储在 MySQL 数据库中。对于每个新到达的项目。

  • (1) 解析传入项。
  • (2) 执行几次“INSERT ... ON DUPLICATE KEY UPDATE”

我使用INSERT ... ON DUPLICATE KEY UPDATE来消除到数据库的额外往返。

在尝试提高整体性能的同时,我考虑过通过以下方式进行批量更新:

  • (1) 解析传入项。
  • (2) 使用“INSERT ... ON DUPLICATE KEY UPDATE”生成 SQL 语句并附加到文件中。

定期将文件中的 SQL 语句刷新到数据库中。

两个问题:

  • (1) 这会对数据库负载产生积极影响吗?
  • (2) 我应该如何将语句刷新到数据库中,以便仅在完全刷新后重建索引?(使用交易?)

更新:我正在使用 Perl DBI + MySQL MyISAM。

提前感谢您的任何评论。

4

2 回答 2

3

如果您的数据不需要立即进入数据库,您可以在某处缓存插入数据,然后发出更大的插入语句,例如

在重复更新时插入 table_name (x, y, z) 值 (x1, y1, z1), (x2, y2, z2), ... (xN, yN, zN) ...;

To be clear, I would maintain a list of pending inserts. In this case a list of (x,z,y) triplets. Then once your list exceeds some threshold (N) you generate the insert statement and issue it.

I have no accurate timing figures for you, but this increased performance roughly 10 times when compared to inserting each row individually.

I also haven't played with the value of N, but I found 1000 to work nicely. I expect the optimal value is affected by hardware and database settings.

Hope this helps (I am also using MyIsam).

于 2010-01-18T18:11:39.650 回答
2

你没有说你正在运行什么样的数据库访问环境(PERL DBI?JDBC?ODBC?),或者你正在使用什么样的表存储引擎(MyISAM?InnoDB?)。

首先,您选择 INSERT ... ON DUPLICATE KEY UPDATE 是对的。好举动,除非你能保证唯一的钥匙。

其次,如果您的数据库访问环境允许,您应该使用准备好的语句。如果您将一堆语句写入文件,然后让数据库客户端再次读取该文件,您肯定不会获得良好的性能。直接从使用传入数据流的软件包执行 INSERT 操作。

第三,选择合适的表存储引擎。MyISAM 插入将比 InnoDB 更快,因此如果您正在记录数据并稍后检索它,那将是一个胜利。但是 InnoDB 具有更好的事务完整性。如果您真的要处理大量数据,并且不需要经常阅读,请考虑使用 ARCHIVE 存储引擎。

最后,考虑在一批 INSERT ... 命令开始时执行 START TRANSACTION,然后在固定行数(如 100 左右)之后执行 COMMIT 和另一个 START TRANSACTION。如果您使用的是 InnoDB,这将大大加快速度。如果您使用的是 MyISAM 或 ARCHIVE,那没关系。

您的重大胜利将来自准备好的声明内容和存储引擎的最佳选择。

于 2009-11-21T03:14:28.153 回答