#performance #hibernate #groovy
#Производительность #гибернация #groovy
Вопрос:
Я унаследовал довольно сложное приложение groovy и пытаюсь понять, как я могу лучше решить некоторые из существующих в настоящее время неприятных шаблонов запросов.
Просто у меня есть что-то вроде:
Class A {
User user
Bravo bravo
static hasMany = [foo: Foo, bar: Long]
}
Class Foo {
User user
Delta delta
static belongsTo = [a: A]
static hasMany = [woo: Woo]
}
Class Woo {
User user
Alpha alpha
static belongsTo = [foo: Foo]
}
Я пытаюсь сделать A.findAllByUser(user)
то, что возвращает мне a <List>A
, однако, когда я начинаю перебирать этот список, я сталкиваюсь с сотнями запросов, которые еще bravo
больше расширяются и foo
.
Я попытался добавить Foo fetch:"join"
к классу Foo и Woo fetch: "join"
классу Woo, однако это означает, что КАЖДЫЙ запрос, который касается этих двух, всегда будет выполнять эти запросы (и все еще не решает сотни запросов bravo
.
Я довольно новичок, когда дело доходит до использования HQL, однако это вызывает некоторые серьезные проблемы с производительностью и масштабированием больших запросов. Есть ли лучший способ решить эту проблему (и, надеюсь, избежать сотен запросов select)?
Комментарии:
1. Когда вы выполняете итерацию
A
, вы также читаете что-то изA.foo
илиA.bravo
? ДажеtoString
может привести к считыванию этих полей и, следовательно, к загрузке hibernate2. это приложение groovy или grails / gorm?
Ответ №1:
Похоже, вы используете GORM (который является ORM, используемым фреймворком Grails).
Чтобы решить вашу проблему, вам нужно решить, какой у вас наиболее распространенный вариант использования. Если вы хотите продолжать ленивую выборку по умолчанию, вы можете локально изменить стратегию выборки, когда вам нужно: A.findAllByUser(user, [fetch: join])
.
Если, с другой стороны, вы хотите сделать быструю выборку значения по умолчанию, но хотите отключить его локально, я считаю, что вам следует использовать lazy: false
вместо fetch: join
в вашем классе домена, потому что это безопаснее с ассоциациями «один ко многим». И вы должны иметь возможность отключить его для любого заданного запроса (например A.findAllByUser(user, [lazy: true])
.
Смотрите здесь .