Skip to main content
Known Participant
October 4, 2010
Question

Reducing Database Call Techniques...query caching the only way?

  • October 4, 2010
  • 3 replies
  • 959 views

What's the most efficient way to reuse data that gets called on practically every page of an application?

For instance, I have a module that handles all my gateways, sub pages and subgateways etc etc.  This will only change whenever a change is made to the page structure in the admin portion of the application.  It's really not necessary to hit the database everytime a page loads.  Is this a good instance to use query caching?  What are the pros, cons and alternatives?  I thought an alternative might be to store in a session, but that doesn't sound too ideal.

Thanks!

Paul

    This topic has been closed for replies.

    3 replies

    Community Expert
    October 5, 2010

    Query caching is usually the easiest way to implement caching, since it doesn't require any other code changes in most cases. And it's usually good enough that you don't have to chase additional performance (in an intranet app, for example). In addition, it will provide better performance than caching in the session in most cases, unless each user runs a different query in which case it's about the same either way.

    But you can do better. You can cache generated HTML in memory or on the filesystem. CF gives you ways to do either, using custom tags like CF_ACCELERATE and built-in tags like CFCACHE, and often that will provide the best performance, since you no longer even have to do the page generation for at least that section of the page.

    Honestly, though, if the performance is satisfactory now with query caching, it's probably not worth your while to chase a few additional milliseconds.

    Dave Watts, CTO, Fig Leaf Software

    Dave Watts, Eidolon LLC
    BKBK
    Community Expert
    Community Expert
    October 4, 2010
    What's the most efficient way to reuse data that gets called on practically every page of an application?

    That sounds like a question from the certification exam. The answer is to store the data in session or applicaton scope, depending on the circumstances. If the data depends on the user, then the answer is session. If the data persists from user to user, then it is application.

    admin portion of the application.

    Suggests users must log in. Otherwise you cannot distinguish admin from non-admin.

    This will only change whenever a change is made to the page structure in the admin portion of the application.

    Then I would go for storing the data in application scope, as the admin determines the value for everybody else. However, the session acope also has something to do with it. Since the changes are only going to occur in the admin portion, I would base everything on a variable, session.role.

    You cache the query by storing it directly in application scope within onApplicationStart in Application.cfc, like this:

    <cfquery name="application.myQueryName">

    </cfquery>

    The best place for the following code is within onSessionStart in Application.cfc.

    <!--- It is assumed here that login has already occurred. Your code checks whether

    session.role is Admin. If so, make the changes. --->

    <cfif session.role is 'admin'>

    <!--- Make changes to the data in application.myQueryName, otherwise do nothing --->

    </cfif>

    Added edit: On second thought, the best place for setting the application variable is in onApplicationStart.

    Known Participant
    October 5, 2010

    Hmm...let me clarify.

    The site menu is currently generated by a module that runs a query over each gateway menu item and builds the sub pages and sub gateways etc.  It will run the query based off of a parent id passed to it.  So if I have 5 gateway menu items, that module/query is run at least 5 times upon each page load during a users visit, cycling through each parent id to generate the menu for that section.

    I was wondering if I should store the entire menu in an array/structure mix one time and just output that instead of hitting the database each time.

    If that's the case, when a change to the menu is made in the CMS how would I force a refresh of that structure for all the users on the site?  Is there a clear cache function I could run??  I guess I could flag it in the database and run a check on that, if it's flagged, run the query, if not pull from the application scope.

    Hope I didn't confuse the issue more.

    Community Expert
    October 5, 2010

    You could store the generated menu in memory, then overwrite it when it's changed. For example, assuming everyone gets the same menu, you could write it to the Application scope, then in the code that processes database changes you could add a bit that writes the new value to the Application scope.

    And again, you don't even need to store arrays and structures, you could just store the generated HTML/CSS/JS/whatever directly, if you wanted to. That would not only prevent having to run the query again, but would also prevent having to build the menu from the data.

    Dave Watts, CTO, Fig Leaf Software

    Dave Watts, Eidolon LLC
    ilssac
    Inspiring
    October 4, 2010

    That or store the resulting data into an application wide variable scope, such as "Applicaiton" or "Server" or another relevant persistant and shared scope.

    Participating Frequently
    October 4, 2010

    Yeah, I'd say it depends on what sort of data. If it's something that should change every few minutes to hours, I'd use a cached query (i.e. to pull new news items for a ticker). If its something that only changes every few days use an application scope variable.