gpt4 book ai didi

mysql - Grails addTo* 与事件的性能缓慢

转载 作者:行者123 更新时间:2023-11-29 07:34:27 27 4
gpt4 key购买 nike

在我的 Grails 应用程序中,我非常兴奋地使用了一些技术,但最近我遇到了一些性能问题,我将描述我的情况:

  • 一张表包含 400 万以上的数据;
  • 我正在使用事件总线 API;
  • Grails 2.2.3;
  • MySQL 数据库;

当客户端创建新房间时,也会创建一些Alloc。

pseudo-code:
Room {
hasMany = aloccs: Alloc
}

看看这段代码(不是真正的代码,但具有相同的等式):

@Listener(topic="topicAlocCreator")
def alocCreator(EventMessage<Long> message) {

LocalDate start = new DateTime().toLocalDate()
LocalDate end = new DateTime().plusYears(2).plusMonths(6).toLocalDate()
LocalDate tmp = start


Room room = Room.get(message.data)
List channels = Channel.list
while(tmp.compareTo(end) <= 0) {
for(channel in channels) {
room.addToAlocs(new Aloc(0, 0, tmp.toDate(), channel))
}
tmp = tmp.plusDays(1)
}

//end of method
}

这段代码工作正常,但它生成了很多分配对象并将其放入 hibernate session 中。

使用flush来完成这项工作的正确方法是什么?批?- 对方法的调用是异步的。

这段代码在(07/14)之前工作得很好,但是在这几天里它非常慢,大约需要 1.30 分钟才能在数据库中插入 10K 的分配;

非常感谢您的建议。

最佳答案

因为 allocs 是一个 Set(定义 hasMany 关系时默认的 Grails 集合类型),Grails 必须将整个集合加载到为了保证唯一性,可以在插入之前存储内存。

看看 Bert Beckwith 的 presentation关于使用 GORM 集合对性能的影响。

我认为你有几个选择。您可以完全放弃集合引用,只需像这样定义您的类:

class Alloc {
Room room
}

class Room {
//no reference child Allocs
}

或者,您可以将 allocs 集合定义为一个包:

class Alloc {
static belongsTo = [room: Room]
}

class Room {
Collection allocs
static hasMany = [allocs: Alloc]
}

在这种情况下,不需要唯一性检查,并且 addTo... 方法不需要将每个 Alloc 实例加载到内存中。然而,您将负责自己维护独特性......

Reference

关于mysql - Grails addTo* 与事件的性能缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31343722/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com