在这个简单的场景中,您将如何提高MySQL吞吐量?

时间:2010-03-10 19:28:04

标签: java mysql optimization

我有一个相对简单的对象模型:

ParentObject
    Collection<ChildObject1>
    ChildObject2

保存此对象模型时的MySQL操作执行以下操作:

  • 更新ParentObject
  • 删除ChildObject1表格中的所有先前项目(约10行)
  • 插入所有新ChildObject1(再次,约10行)
  • 插入ChildObject2

对象/表格不起眼 - 没有strings,而主要是intslongs

MySQL目前每秒可以节省大约20-30个对象模型实例。当这进入生产时,它将进行超过一百万次的保存,目前的速度将需要10多个小时,这对我来说并不好......

我正在使用Java和Spring。我已经分析了我的应用程序,并且瓶颈在长距离调用MySQL中。

您如何建议我提高吞吐量?

2 个答案:

答案 0 :(得分:1)

通过跟踪对象上的脏标志(尤其是子对象集合),可以获得一些加速。您只删除/更新脏的。根据每次写入时它们的百分比变化,您可以节省一大块。

您可以做的另一件事是通过批量更新在预准备语句上进行批量写入。 (查看PreparedStatement.addBatch())这可能会快一个数量级,但可能无法按记录记录,例如。可能看起来像:

  • 将所有脏标记的子项删除为单个批处理命令
  • 将所有父级更新为单个批处理命令
  • 将所有脏标记的子项作为单个批处理命令插入。

请注意,由于您正在处理数百万条记录,您可能无法将它们全部加载到地图中并立即转储它们,因此您必须将它们流式传输到批处理程序并转储一次更改db 1000记录。完成此操作后,实际速度对批量大小敏感,您必须通过反复试验来确定默认值。

答案 1 :(得分:-1)

从表中删除任何现有的ChildObject1记录,然后从ChildObject1对象的当前状态插入Parent个实例对我来说似乎没有必要。所有子对象的值是否与先前存储的值不同?

更好的解决方案可能只涉及在需要时修改数据库,即ChildObject1个实例的状态发生变化时。

为这种类型的东西滚动你自己的持久性逻辑可能很难(你的持久层需要在检索它们时知道ChildObject1个对象的状态,以便在保存时将它们与对象的版本进行比较)。您可能希望使用像Hibernate这样的ORM,这样可以很好地了解何时需要更新数据库中的记录。