优化MySQL插入以处理数据流

时间:2009-11-21 01:05:10

标签: mysql optimization bulkinsert

我正在使用高速数据流,并执行以下步骤将数据存储在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。

提前感谢任何评论。

2 个答案:

答案 0 :(得分:3)

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

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

要清楚,我会维护一个待处理插入列表。在这种情况下,(x,z,y)三元组列表。然后,一旦列表超过某个阈值(N),就会生成insert语句并发出它。

我没有准确的计时数据,但与单独插入每行相比,这个性能提高了大约10倍。

我也没有使用N的值,但我发现1000可以很好地工作。我希望最佳值受硬件和数据库设置的影响。

希望这有帮助(我也在使用MyIsam)。

答案 1 :(得分:1)

你没有说你正在运行什么样的数据库访问环境(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,则无关紧要。

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