在非常小的插入中将大量数据插入数据库

时间:2010-06-28 21:47:33

标签: java mysql performance jdbc

所以我有一个数据库,其中有很多数据从java应用程序中插入。 usualy我插入到table1中获取最后一个id,然后再次插入table2并从那里获取最后一个id,最后插入table3并获取该id并在应用程序中使用它。我每隔10-15分钟插入大约1000-2000行数据。

在生产网络服务器上使用大量小插入和选择并不是很好,因为它有时会使服务器陷入困境。

我的问题是:有没有办法在不使用如此大量的选择和插入的情况下将多个数据插入table1,table2,table3?我缺少一种sql-fu技术吗?

3 个答案:

答案 0 :(得分:5)

由于您可能依赖于auto_increment主键,因此您必须一次执行一次插入操作,至少对于table1和table2。因为MySQL不会给你提供超过最后生成的密钥。

你永远不必选择。您可以使用getGeneratedKeys()方法从Statement中获取最后插入的id。请参阅连接器/ J的MySQL手册中显示的示例:

http://dev.mysql.com/doc/refman/5.1/en/connector-j-usagenotes-basic.html#connector-j-examples-autoincrement-getgeneratedkeys

其他建议:

  • 对table3使用多行INSERT语法。
  • 导入时使用ALTER TABLE DISABLE KEYS,并在完成后重新启用它们。
  • 使用显式交易。即在数据加载例程之前开始事务,最后提交。我可能也会在每1000行table1之后提交。
  • 使用准备好的陈述。

不幸的是,您无法使用最快的方法来批量加载数据LOAD DATA INFILE,因为这不允许您获取每行生成的ID值。

答案 1 :(得分:2)

这里有很多话题要讨论:

  1. 如果这些INSERT中的每一个都是另一个网络往返,那么网络延迟可能会导致您死亡。尝试对您的请求进行批处理,这样他们只需要对整个事务进行一次往返。
  2. 说到交易,你没有提到它们。如果所有这三个INSERT都需要单个工作单元,那么最好正确处理事务。如果你不知道如何,更好地研究它们。
  3. 尝试缓存请求,如果它们被重复使用的话。最快的往返是你没有做到的。

答案 2 :(得分:1)

您可以重新设计数据库,使主键不是数据库生成的自动递增值,而是客户端生成的UUID。然后,您可以预先为每个记录生成所有键,然后根据需要批量插入。