2010-03-10 72 views
1

我有一个相对简单的对象模型:如何在这个简单的场景中改进MySQL吞吐量?

ParentObject 
    Collection<ChildObject1> 
    ChildObject2 

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

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

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

MySQL目前每秒钟保存大约20-30个对象模型实例。当这种情况发生时,它将会执行超过一百万次的保存,这在目前的速度下将花费10个小时以上,这对我来说并不好......

我正在使用Java和Spring。我已经对我的应用程序进行了描述,并且瓶颈在远程调用MySQL中。

你会怎么建议我增加吞吐量?

+0

你如何通过脚本执行这些操作?如果是这样,什么语言? – Seaux 2010-03-10 19:37:33

+0

更新了问题..对不起 – MalcomTucker 2010-03-10 19:41:09

回答

-1

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

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

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

+1

hibernate将是一个可怕的想法,直接与批处理JDBC是你想要的。 – 2010-03-10 19:58:46

+0

我正在用其他对象监视脏状态,但不能与子对象一起使用,因为它们是其他对象的聚合。这些聚合可能是新的,修改或删除的,而不是删除和重新插入,这实际上涉及更多的数据库工作。 – MalcomTucker 2010-03-10 20:20:10

1

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

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

  • 删除所有脏籍儿童作为一个批处理命令
  • 更新所有家长作为一个批处理命令
  • 插入所有脏国旗的孩子作为一个批处理命令。

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

+0

我想过这个,但是如果我分解对象并对它们进行批处理,我可能会产生数据不一致 - 所以如果用户在删除子项之后但在插入新子项之前查询父对象,它们将检索不完整的数据集。这也将是不可接受的。这是否有道理? – MalcomTucker 2010-03-10 20:09:55