Please enter name
please enter valid email
please enter comment
Please enter correct code

Improving your Grails application performance (Look Jim no stored procedures)

Contributed by uttam on 8 Feb 2013

Improving your Grails application performance

(Look Jim no stored procedures)

It’s always great to have application running on high CPU & more memory and that way you can always hide your code and environment mistakes. I did the same when I had a large instance of EC2 and IOPS enabled on the RDS, I designed and developed code which was less effective in terms of performance. 

But one day I moved my code to a medium EC2 with RDS having no IOPS, it all ran slow and more slow.

My environment was Grails 2.1.1 & I had many plugins and huge DB with transactions which was like trying to insert 100k records frequently.

Steps I followed

Read all the blogs & I landed on Mr. Burt’s presentation

http://www.infoq.com/presentations/GORM-Performance (Great presentaiton)

I picked one immediate helper from Burt (which someone stopped during the presentation and asked about)

grails>grails console

The console helped me a lot for faster development, I could skip all the hoops of navigating through screens to get my code executed, no authentication, no steps just run :-).

I pasted all my code in the console, Ctrl + R and it ran!!

I changed my domain module to include only a reference of the parents key instead of the whole object

Example:

Older Version 

public domain CustomerWeeklyServiceMenu {

String id

Date dateCreated

Date lastUpdated

BigDecimal pricePerServing

BigDecimal servingsQuantity

CustomerWeeklyServiceMenu customerWeeklyServiceMenu

Menu menu

static transients = ['excluded']

..

}

New Version

public domain CustomerWeeklyServiceMenu {

String id

Date dateCreated

Date lastUpdated

BigDecimal pricePerServing

BigDecimal servingsQuantity

CustomerWeeklyServiceMenuId

MenuId

static transients = ['excluded']

..

}

As you can see now I don’t have the Parent Objects in the domain rather, I now have the ids of those domain classes (or tables)

This is a good step to start with as Burt clearly mentions how Hibernate works with Collections and what can be the draw back if you don’t do it this way.

Second level Caching

hibernate {

cache.use_second_level_cache = true

cache.use_query_cache = true

cache.provider_class = ‘org.hibernate.cache.EhCacheProvider’

}

This will enable Hibernate’s second level of caching for us. You need to add this in your DataSource.groovy

You would need to perform changes in your domain class which you want to make use of the second level caching.

static mapping = {

cache usage: ‘read-only’

}

From Mr. Burts’s presentation:

The 1st level cache is the Hibernate Session

Can significantly reduce database load by keeping instances in memory

Can be distributed between multiple servers to let one instance load from the database and share updated instances, avoiding extra database trips

● “cache true” creates a read-write cache, best for read-mostly objects since frequently-updated objects will result in excessive cache invalidation (and network traffic when distributed)

● “cache usage: ‘read-only’” creates a read-only cache, best for lookup data (e.g. Countries, States, Zip Codes, Roles, etc.) that never change

DomainClass.get() always uses the 2nd-level cache

By default nothing else always uses the cache but can be overridden

Then you need to configure your Ehchace.xml

INDEXES

We created indexes on parent classes after using explain on Mysql tables. It did help us to certain extent.

Batch Updates

I did CleanGorm after performing batch inserts.

if (index % Constants.SQL_BATCH_SIZE == 0) cleanUpGorm(index)

def cleanUpGorm(def index) {

def session = sessionFactory.currentSession

session.flush()

session.clear()

}

But I still did not see that big performance Run, then after reading more blogs and more books on hibernate, a thought came across if the session cache was very large. But that was the reason.

Next, I read that Grails has FlushMode as “AUTO”, so I referred to this page on Hibenate

What I understood was that Grails before querying makes a “session” FLUSH. That is very very bad !!.

I imported the org.hibernate.FlushMode & I put this line

session.setflushMode(FlushMode.COMMIT)

ICE breaker…..that’s it !! Now I had 450K records in an hour instead of 20K in 2 hours.

 

Visit us at Neevtech.com to know more about our offerings.

Leave a Comment

Security Code: