Strange Caching

February 21, 2007 · By Gert Franz · 2 Comments

A thing I noticed while playing with some performance tests is that MX has a strange behaviour when caching queries. Well in fact I guess it is not strange but worth mentioning.The last couple of days there was a larger discussion on CF-Talk on whether to cache one large query or many smaller ones.
The thing is that large queries, even if cached consume some time when refeched from Coldfusions memory.
In my particular case I pulled a query with 120000 records in order to test some performance switches in Railo. Just for fun, since I didn't want to wait for the SQL-Server to fetch all the records from the database again I wanted them to stay cached for a couple of minutes. Here's the code I used:
<cfset iTimer = getTickCount()>
<cfquery name="getRecords" datasource="testdb" cachedwithin="#createTimeSpan(0,0,3,0)#">
Select * from logs
</cfquery>
<cfset iTimer = getTickCount() - iTimer>
<cfoutput>#iTimer#ms</cfoutput>
My query returns 120,000 records. SQL-Server delivers them in 1.7 seconds. The funny thing is, that when I reexecute the same template again within the cached time Coldfusion still needs over a second to fill the query variable with the cached query.
The results
ExecutionCFMXRailo
First (Ø):1,721ms704ms
Further (Ø):1,157ms0ms

If I turn on debugging just for one case it displays:


SQL Queries


getRecords (Datasource=davidoff, Time=1265ms, Records=121267, Cached Query) in D:\Projects\davidoff\test.cfm @ 08:40:55.055


In fact I really do not know why. I haven't looked at the generated .java file but it seems that the cached query is refilled record by record from a cached variable into my local variable called "getRecords".

This way of executing has imho two drawbacks: 1. Coldfusion consumes twice as much memory for caching one query. First for the cached one and second for the copied on (assuming the query get's copied, which it seems)
2. Coldfusion takes mor time to fill the query even if cached since the records have to be copied from the cached query into the local query variable.

Well this is the only explanation I have for this effect. Maybe there is an other reason for this.
Railo caches a query in a different way. When a query get's cached and an other query needs to be filled with the same cached results, Railo points to the same cached query without refilling anything.
You may argue what happens when a cached query is changed by using queryAddRow(), or querySetCell()?
Railo only in this case copies the cached query into a new one and applies the functions. Since the changing of a query is extremely rare, this is much more performant than copying it everytime you access a cached query.

Tags: Comparison · Performance

2 responses so far ↓

  • 1 Nolan Erck // Feb 21, 2007 at 10:17 PM

    I haven't tested this yet, but I wonder if using the blockFactor attribute on your cfquery tag would change this behavior at all???

    -nolan
  • 2 Gert Franz // Feb 22, 2007 at 9:36 AM

    No I it does not, since the blockFactor has only an impact on how many records are retrieved from the database server. So it is a setting for different database servers. The livedocs say to this attribute:
    &quot;Maximum rows toget at a time from server... Might not be supported by some database systems&quot;
    This clearly indicates that it is something special for different database types. So the default handling of queries like caching is not affected.
    In my test I found out, that it has absolutely no effect on the caching, but on the data retrieval.

    Gert

Leave a Comment

Leave this field empty: