on Expert Tips

Cache for your database queries

4 comments
speedo
Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedInShare on RedditShare on StumbleUpon

When there is a lot of people on your site, they read many articles (which is good). That leads to big number of database retrievals and your database is potential bottleneck (which is bad).

So what will we do about it? The best way is to cache the database results, so when first user reads an article, it is fetched from the database, but when the same article is requested again, then we read it from the cache and thus allowing our MySql server to rest a bit.

There are many types of caching mechanisms like memcached, APC, eAccelerator but for the simplicity of this tip, we will use plain file to hold our cache data. This is enough in most of cases.

So let’s see how our caching class looks like:

/**
* @desc Class that implements the Cache functionality 
*/
class Cache {

    /**
    * @desc Function read retrieves value from cache
    * @param $fileName - name of the cache file
    * Usage: Cache::read('fileName.extension')
    */
	function read($fileName) {
		$fileName = '/path/to/cache/folder'.$fileName;
		if (file_exists($fileName)) {
			$handle = fopen($fileName, 'rb');
			$variable = fread($handle, filesize($fileName));
			fclose($handle);
			return unserialize($variable);
		} else {
			return null;
		}
	}
	
    /**
    * @desc Function for writing key => value to cache
    * @param $fileName - name of the cache file (key)
    * @param $variable - value
    * Usage: Cache::write('fileName.extension', value)
    */
	function write($fileName,$variable) {
		$fileName = '/path/to/cache/folder'.$fileName;
		$handle = fopen($fileName, 'a');
		fwrite($handle, serialize($variable));
		fclose($handle);
	}
    
    /**
    * @desc Function for deleteing cache file
    * @param $fileName - name of the cache file (key)
    * Usage: Cache::delete('fileName.extension')
    */
    function delete($fileName) {
        $fileName = '/path/to/cache/folder'.$fileName;
        @unlink($fileName);
    }

}

Save above code as cache.php. We’ll use it later.

Code is well commented so I will not explain the details. Notice that in function write we use function serialize and in read unserialize . As PHP manual says:

Serialize generates a storable representation of a value. This is useful for storing or passing PHP values around without losing their type and structure.

So we are just adjusting PHP value in more “storable” way.

Here is how you can use this in your application:

// include the class
require_once('cache.php');
//instantiate it
$cache = new Cache();
//let's check if some cache file exists
$data = $cache->read('test_17.tmp'); //17 is id of the article, for example
// it doesn't exist, fetch data from database
if (empty($data)) { 
    $sql = "SELECT image, user_id, content FROM table WHERE id = 17";
    $data = $db->select_list($sql); // just an example 
    $cache->write('test_17.tmp', $data);     
}
// then use the data as you would normally
foreach($data as $row) {
    ........
}

This way you will gain some speed and your database server will thank you. But there is a catch! It is very, very important not to forget to clear this cache if something gets changed on that particular article. So do not forget to add this lines after your update the article:

// include the class
require_once('cache.php');
//instantiate it
$cache = new Cache();
//updating the article example
$data = 'some array for updating';
$db->update_record('table', $data);
$cache->delete('test_17.tmp');

Now you clear the cache and the new version of the article will appear, and the new Cache file will be created.

Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedInShare on RedditShare on StumbleUpon



  • exdesignorama

    Very nice, I’ll give it a try 🙂

  • Zoran Jambor

    Very nice indeed!

    But using files to store information could also be inefficient, right? Isn’t fopen a bit slow?

    What about other caching mechanisms? Is there any other way, besides using files to cache data?

    I think that this could well be the subject for another article. I would love to learn more about it. 🙂

  • Hyder

    Very nice article indeed . never knew of this technique . Actually this gonna help me for some big personal project am working on .

  • pppp