corner image corner image
corner image corner image
corner image corner image
corner image corner image
corner image corner image
corner image corner image
corner image corner image

Caching SQL results with PHP

I’ve been looking around lately on the best way to cache SQL results in PHP. I found some interesting articles posted in lots of places, but I didn’t find any that exactly matches my needs. The problem I have on hand is basically the same every growing website faces: decreasing mean resource usage per page request.

Now - this is my plan A to keep up with the website’s growth without a lot of hardware upgrades. There is a plan B, but I will keep that to a later post.

Usually, the time consumed by executing the SQL statements is more than 80% of the whole script time. Reducing this time will significantly reduce the resource usage. CPU is not the bottle neck, usually SQL queries result in a significant disk access especially if there’s a lot of inserts/updates/deletes.

The easiest and best way I found is to use PHP’s serialize to store the SQL results. This requires that we fetch all the rows we’re dealing with. So the sequence of operations is to check the cache file, if expired or does not exist then fetch all the rows from the result set, serialize in one variable, write it to the cache file.

  1. <?
  2. require_once "utils.php";
  3.  
  4. $cache_prefix=‘/tmp/clkercache/’;
  5.  
  6. function cache_fetch($filename, $expiration=3600)
  7. {
  8.   global $cache_prefix;
  9.   $filename=$cache_prefix.$filename;
  10.  
  11.   if (!file_exists($filename)) return false;
  12.   if (time(0)-filemtime($filename)>$expiration) return false;
  13.  
  14.  
  15.   return $data;
  16. }
  17.  
  18. function cache_store($filename,$data)
  19. {
  20.   global $cache_prefix;
  21.   $filename=$cache_prefix.$filename;
  22.  
  23.   @mk_dir($filename);
  24.   return file_put_contents($filename,base64_encode(serialize($data)));
  25. }
  26. ?>
  27.  

So the way to use the caching functions would be something similar to this:

  1. <?
  2. if ( !($pictures=cache_fetch("mypictures.cache")) ){
  3.   $res=query("select pictureid from pictures order by rating15days desc limit 100");
  4.   while ($row=fetch_array($res))
  5.     $pictures[]=$row;
  6.  
  7.   cache_store("mypictures.cache",$pictures);
  8. }
  9. ?>

So how to do that if you have multiple queries? The way I store my cache files is by giving them suffix or prefix names depending on what is being stores. For example a file that store the pictures that are related to a picture whose id is 1500 being displayed, will be called related-1500.cache. For more complicated cases like searches, I would use the md5sum of the request URI.

The results were good. Using apache bench I tested the homepage. Before any caching it used to support 3 pages per second. After caching the result was 35. I think in my current situation with my current traffic, this is a very good result.

One might think so what does it take to generate pages at a much higher rate - say 300, 400 or even a 1000 or more? Well, that’s my plan B, and I’ll discuss that in more detail in another post. This plan B will generate that much pages per second.

Technorati Tags: , , , , , ,

Tags: , , , , , ,

corner image corner image

corner image corner image

One Response to “Caching SQL results with PHP”

  1. Clker.com - weblog » Blog Archive » Caching SQL with PHP Says:

    [...] art cleanup What are the candidates web serv… Firefox 3 this Tuesday Caching SQL results with PHP Gatner “Windows is collapsing” Multiple SVG uploads Creating a tar gz on the fly [...]

Leave a Reply

corner image corner image
5,275 spam comments
blocked by
Akismet