Как обойти потенциальную проблему производительности при использовании отношения Grails hasMany? - PullRequest
1 голос
/ 14 ноября 2008

Имеются следующие классы доменов:

class Post {
   SortedSet tags
   static hasMany = [tags: Tag]
}

class Tag {
   static belongsTo = Post
   static hasMany = [posts: Post]
}

Насколько я понимаю, использование hasMany приведет к отображению в спящем режиме Set. Однако для поддержания уникальности / порядка Hibernate должен загрузить весь набор из базы данных и сравнить их хэши.

Это может привести к значительным проблемам с производительностью при добавлении и удалении сообщений / тегов. если их наборы становятся большими. Как лучше обойти эту проблему?

Ответы [ 3 ]

1 голос
/ 20 ноября 2008

Hibernate / GORM не обеспечивает порядок в отображении по умолчанию. Следовательно, для сортировки не нужно загружать элементы из базы данных. У вас в руках будет куча идентификаторов, но на этом все.

См. 19.5.2: http://www.hibernate.org/hib_docs/reference/en/html/performance-collections.html

В целом, Hibernate / GORM будет иметь лучшую производительность, чем вы ожидаете. Если и до тех пор, пока вы не сможете реально доказать реальную проблему производительности, доверяйте фреймворку и не беспокойтесь об этом.

0 голосов
/ 20 ноября 2008

Документы Grails обновлены:

http://grails.org/doc/1.0.x/

В разделе 5.2.4 они обсуждают потенциальные проблемы производительности для типов коллекций.

Вот соответствующий раздел:

Замечание о типах и производительности коллекции

Тип Java Set - это коллекция, которая не допускает дублирование. Чтобы обеспечить уникальность при добавлении записи в Ассоциацию множеств, Hibernate должен загрузить все ассоциации из базы данных. Если у вас есть большое количество записей в ассоциации, это может быть дорого с точки зрения производительности.

Такое же поведение требуется для типов списков, поскольку Hibernate должен загрузить всю ассоциацию, чтобы поддерживать порядок. Поэтому, если вы ожидаете большое количество записей в ассоциации, рекомендуется сделать ассоциацию двунаправленной, чтобы ссылка могла быть создана на обратной стороне. Например, рассмотрим следующий код:

def book = new Book(title:"New Grails Book")
def author = Author.get(1)
book.author = author
book.save()

В этом примере ссылка на ассоциацию создается дочерним объектом (Book), и, следовательно, нет необходимости напрямую манипулировать коллекцией, что приводит к уменьшению количества запросов и повышению эффективности кода. Если у вас будет Автор с большим количеством связанных экземпляров Book, если вы будете писать код, подобный следующему, вы увидите влияние на производительность:

def book = new Book(title:"New Grails Book")
def author = Author.get(1)
author.addToBooks(book)
author.save()
0 голосов
/ 14 ноября 2008

Порядок набора гарантируется реализацией Set, то есть SortedSet. Если вы не используете List, который отслеживает индексы в БД, порядок выполняется только на стороне сервера.

Если класс вашего домена относится к SortedSet, вам нужно реализовать Comparable, чтобы включить правильную сортировку набора.

Вопрос о производительности на самом деле не является вопросом как таковым. Если вы хотите получить доступ к одному Tag, вы должны получить его по Id . Если вы хотите отсортированные теги, ну, сортировка имеет смысл, только если вы смотрите на Tags, а не на конкретный, поэтому вы в итоге получаете все Tags одновременно. Поскольку сортировка выполняется на стороне сервера, а не на стороне db, разница между SortedSet и обычным HashSet в отношении Db невелика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...