Oracle
  Home arrow Oracle arrow Generic Architecture for Caching Table Data: Hello Cache, How Are You Doing?
Dev Shed Forums  
Administration  
AJAX  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Smartphone Development  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Mobile Linux  
App Generation ROI  
IBM® developerWorks  
Forums Sitemap  
E-Commerce Hosting  
Linux Web Hosting  
Managed Hosting  
Small Business Hosting  
VPS Hosting  
Weekly Newsletter

 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid  
Request Media Kit
Contact Us  
Site Map  
Privacy Policy  
Support  
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
Google.com  
ORACLE

Generic Architecture for Caching Table Data: Hello Cache, How Are You Doing?
By: Mark Vilrokx
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: starstarstarstarstar / 1
    2005-11-01


    Table of Contents:
  • Generic Architecture for Caching Table Data: Hello Cache, How Are You Doing?
  • The Cache Miss Ratio aka DB Reads
  • The Cache Turnover Ratio
  • Reporting the Ratio

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      error-file:tidyout.log Del.ici.ous error-file:tidyout.log Digg
      error-file:tidyout.log Blink error-file:tidyout.log Simpy
      error-file:tidyout.log Google error-file:tidyout.log Spurl
      error-file:tidyout.log Y! MyWeb error-file:tidyout.log Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article

     
     
    ADVERTISEMENT


    Generic Architecture for Caching Table Data: Hello Cache, How Are You Doing?
    ( Page 1 of 4 )

    Now that you have set up a functioning cache, are you sure it's giving you the performance enhancements you need? Keep reading to learn three ways to check the performance of your cache.

    At this stage, we have all the basic functionality in place for our cache to be useful and usable.  We can read and write to it, refresh it, flush it and show its content.  In this part we will add code that allows you to gauge the effectiveness of the cache.  This can be used to help you fine-tune the optimum size of your cache in a particular instance.  Note that this does not add any functionality to the actual cache, it is just a tool that helps you understand how the cache is being used and allows you to make some informed decisions later on.

    The Hit Ratio

    When data is found in the cache, it is called a cache hit, and the effectiveness of a cache is judged by its hit rate.  A cache is only effective if it has a high hit rate.  The hit ratio can be calculated by dividing the number of times a record gets found in the cache (cache hit), versus the number of times a record was looked for:

                # Cache Hits

    Hit Ratio = ------------- * 100

                # Total Reads

    The higher the hit ratio, the better your cache usage, and the more performance gain you are getting from using the cache.  A low cache hit ratio can indicate that the cache size is too small, or that the data you are caching is not suitable for caching, i.e. there are too many distinct values that get queried resulting in high turnover (see later).

    In order to be able to calculate the ratio, we just need to keep track of the number of successful cache reads and the total number of reads.  I do not want to slow down the cache’s performance, however, by gathering all these statistics, so first we introduce another switch to control whether cache stats are gathered or not:

       g_gather_stats     BOOLEAN        := FALSE;

    This is followed by the usual getters and setters:

       PROCEDURE set_gather_stats (p_on IN BOOLEAN)
       AS
       BEGIN
          g_gather_stats := NVL (p_on, FALSE);
       END set_gather_stats;

       FUNCTION gather_stats
          RETURN BOOLEAN
       AS
       BEGIN
          RETURN g_gather_stats;
       END gather_stats;

    We also need places in which we can store the numbers, so let's create some more global variables:

       g_total_reads        PLS_INTEGER    := 0;
       g_total_cache_hits   PLS_INTEGER    := 0;

    And then change our existing code to gather the numbers (if requested):

       FUNCTION read_from_cache (p_dept_id IN dept.deptno%TYPE)
          RETURN department_tp
       AS
          l_dept_data   department_tp;
       BEGIN
          IF (g_dept_cache.EXISTS (p_dept_id))
          THEN
             l_dept_data.NAME := g_dept_cache (p_dept_id).NAME;
             l_dept_data.LOCATION := g_dept_cache
    (p_dept_id).LOCATION;
             IF (gather_stats)
             THEN
                g_total_cache_hits :=   g_total_cache_hits
                                      + 1;

             END IF;
          END IF;

          RETURN l_dept_data;
       END read_from_cache;

       FUNCTION dept_data (
          p_dept_id         IN   dept.deptno%TYPE,
          p_force_db_read   IN   BOOLEAN
       )
          RETURN department_tp
       AS
          l_dept_data   department_tp;
       BEGIN
          IF ((caching) AND (NOT (p_force_db_read)))
          THEN
             l_dept_data := read_from_cache (p_dept_id);
          END IF;

          IF (l_dept_data.NAME IS NULL)
          THEN
             l_dept_data := read_from_db (p_dept_id);

             IF ((l_dept_data.NAME IS NOT NULL) AND (caching))
             THEN
                write_to_cache (p_dept_id, l_dept_data);
             END IF;
          END IF;

          IF (gather_stats)
          THEN
             g_total_reads :=   g_total_reads
                              + 1;

          END IF;
          RETURN l_dept_data;
       END dept_data;

    Now we just need to create a procedure to actually perform the calculation of the ratio:

       FUNCTION cache_hit_ratio
          RETURN PLS_INTEGER
       AS
          l_cache_hit_ratio   PLS_INTEGER;
       BEGIN
          IF (g_total_reads <> 0)
          THEN
             l_cache_hit_ratio := (g_total_cache_hits /
    g_total_reads) * 100;
          END IF;

          RETURN l_cache_hit_ratio;
       END cache_hit_ratio;

    Note that your hit ratio will never be 100% because the cache needs to get filled first, i.e. the first records that get queried will always result in a DB read because there is nothing in the cache yet.  The goal is to get as close to 100% as possible.



     
     
    >>> More Oracle Articles          >>> More By Mark Vilrokx
     

       

    ORACLE ARTICLES

    - Oracle's Turn to Play in the Sun
    - Implementing and Using Oracle`s Restore Poin...
    - Tuning PL/SQL Code
    - Debugging PL/SQL Code
    - Testing PL/SQL Code
    - Working With PL/SQL Code
    - Conditional Compilation for Oracle Database ...
    - Compile-Time Warnings for Oracle DB 10g
    - Compiling PL/SQL Code for an Oracle Database
    - Troubleshooting PL/SQL Code
    - Managing PL/SQL Code
    - Data Manipulation and More for HTML DB Appli...
    - Oracle Database Fundamentals
    - Adding Processes to HTML DB Applications
    - Adding Computations, Processes, and Validati...





    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 4 Hosted by Hostway
    For more Enterprise Application Development news, visit eWeek