How do I get around a potential performance issue when using the Grails hasMany relationship?

Considering the following domain classes:

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

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

      

From my understanding so far, using hasMany

will result in hibernate mapping Set

. However, to maintain uniqueness / ordering, Hibernate needs to load the entire set from the database and compare their hashes.

This can lead to a significant performance issue when adding and removing posts / tags if their sets grow large. What's the best way to get around this issue?

+1


source to share


3 answers


There is no order in the default settings for Hibernate / GORM. Therefore, sorting does not require loading items from the database. You will have your hands on a bunch of IDs, but to that extent.

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



Overall, Hibernate / GORM will have better performance than you expect. If and until you can actually prove a real performance problem, believe in the structure and don't worry about it.

+1


source


The order of the set is guaranteed by the implementation Set

, i.e. SortedSet

... If you are not using List

that keeps track of indexes on the db, the order is only done server side.

If your domain class is in SortedSet

, you must implement Comparable

to enable correct collection collation.



Performance is not a question in and of itself. If you want to access one Tag

, you must access it with Id . If you want to sort the tags, well, sorting will only make sense if you're looking at everything Tags

and not a specific one, so you end up with everything at Tags

once. Since sorting is done on the server side and not on the db side, there is not much difference between a SortedSet

and regular HashSet

regarding Db.

0


source


The Grails docs seem to be updating:

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

Section 5.2.4 discusses potential performance issues for collection types.

Here's the relevant section:

A note about collection types and performance

Java collection type is a collection that does not allow duplication. To ensure uniqueness when adding a record to a Set association, Hibernate must load all associations from the database. If you have a large number of entries in an association, this can be expensive in terms of performance.

The same behavior is required for List types, since Hibernate needs to load the entire association in order to maintain order. Therefore, it is recommended that if you expect a large number of entries in an association that you make the association bidirectional so that the link can be created on the back. For example, consider the following code:

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

      

In this example, the associative link is created by the child element (Book), and therefore there is no need to manipulate the collection directly, resulting in fewer queries and more efficient code. Considering an author with a lot of linked book instances, if you have to write code like below, you will see the performance impact:

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

      

0


source







All Articles