The other day I was looking to improve the performance of specific parts of our Grails application. I quickly found the typical bottleneck in database centric Grails apps: Too many queries were executed because GORM hides away database queries by its built-in persistence methods for domain objects and the extremely nice dynamic finders. In search for improvements and places to use GORM/Hibernate caching I stumbled upon a very good and helpful presentation on GORM-performance in general and especially collection usage. Burt Beckwith presents some common problems and good patterns to overcome them in his SpringOne 2GX talk. I highly recommend having a thorough look at his presentation.
Nevertheless, I want to summarize his bottom line here: GORM does provide a nice abstraction from relational databases but this abstraction is leaky at times. So you have to know exactly how the stuff in your domain classes is mapped. Be especially careful it collections tend to become “large” because performance will suffer extremely. We already observed a significant performance degradation for some dozen elements; your mileage may vary. For many simple modifications on a collection all its elements have to be loaded from the database!
Instead of using
hasMany/belongsTo just add a back reference to the domain object your object belongs to. With the collection you lose cascading delete and some GORM functionality but you can still use dynamic finders and put the functionality to manage associations yourself into respective classes. This may be a large gain in specific cases!
One thought on “GORM-Performance with Collections”
.One of the first things people learn about GORM relationships is that they are loaded lazily by default. Instead GORM will only load a relation when you actually use it..Lets make this a bit more concrete by considering the example from the previous article ..class Location . Normally this is hidden from you by GORM but check out the behaviour of the following ..def p Person.get 1 .assert p.pet instanceof Dog.assert Pet.get 1 instanceof Dog.assert Pet.findById 1 instanceof Dog.assert Pet.list 0 instanceof Dog..Assuming that we have one Person instance and one Pet instance thats a Dog and assuming that the two are related via the pet property the first three assertions will succeed but the last one will not.