Database Object Caching in QCubed

I you think that I should first be talking about how to query database with QCubed, you would be disappointed because am not at all going to talk about that. There are a lot of examples on the QCubed Examples site for that. If you have any problems or queries for that, head on to QCubed examples site and look for yourself (and QCubed is one rare framework which has a examples site covering its working in a full blown examples site). However, there are interesting things which you can do with QCubed and one of those things is Caching your database results. Before we get into how to do caching Database results in QCubed, let us first see what caching is.

What is Caching after all?

The word cache literally means "a place to hide something for future use". In case of computing, it is one place where you store data so that you can use it later. If you have had some lessons about the memory hierarchy, you would know that a cache sits between the processor and the secondary storage like disks so that you could retrieve data faster from it! I am not going to explain caching in detail. If you are unsure about what this is, head on to Google or Wikipedia and read about it. In case of web applications, cache is of an utmost use to developers. They (developers) can write the program to query the database, retrieve results and place them in the cache. Next time when some data is needed, it is first looked up in the cache; if it is there in the cache, it is used or else, the database is queried and results are stored in the cache and sent to the client (browser, or any other place where it is needed).

Caching is done to make things faster and if you were to think about what I wrote just above, you might want to think that Caching will consume more time than usual and you wouldn't be wrong if you did not consider placing things in the RAM. Caches usually reserve some amount of RAM (or system's Primary memory​) and keep on storing more and more things there until the whole space reserved is filled up. What happens then if the cache is needed to store more data, you ask? Well, the caching system will remove the entry which has been used least number of times or least recently used. Currently, QCubed supports one of the most widely used Caches all over the world (and mind you, Facebook uses it too!) named memcached.

QCubed and caching

If you do not know, QCubed is a fully Object Oriented and it treats the database tables as classes and the rows in them as objects of those classes. While QCubed is reasonably fast, it comes with a trade-off: slower operation than what you could get with a self made script. But then, you cannot have everything in the same package, right? Well, no. QCubed supports Caching and if used properly, it can increase the speed significantly.

With QCubed, you are free to write your own SQL but why do so when it already creates all the necessary classes and methods for you! The reason QCubed's QQuery​ mechanism would slow things down a little lies in the fact that before doing anything with the data extracted from your database, QCubed first converts the data into PHP objects for the table from which the data was extracted. For nested queries (that translates to the ​QQ::Expand​ clause) it means that a lot of time is taken. QCubed will automatically cache any object retrieved with the code-generated 'Load' function. So if you query with primary keys a lot, you are on a faster road than usual! Oh and if you are thinking that QCubed will take more than 1 minute to get 20 results from a million rows table, you are wrong. With the 'Order By' clause in place, it will create objects for only those rows that you wanted be taken out of database. One might ask what are the benefits of that if you cannot cache results for nested queries. The reason is rather difficult to explain unless you happen to understand how QCubed works internally (but then, you wouldn't be reading this page anyway). So I will try it.

When we use QQ::Expand, QCubed will try to take out only those connected properties (the relationship of the table with other tables using foreign keys) from the objects as requested in the queriy and attach them to the parent object. That means if you were to query using QCubed for an object with only 1 expansion out of 3 possible expansions and it were placed in cache, it might just turn up with a object which was not 'fully expanded' and that certainly can hit you in the head when you try to access that object again (it is just like you query a table to extract 4 columns from a row out of 10 columns and cache it, and then assume that the cached object contain all the 10 columns)! This is one reason why QCubed does not implement caching for nested queries. Secondly, if you were to expand all objected with all the relationships they have with all other tables, you might end up with every object having a lot of data which is not always​ required. This translates into a lot of unwanted data cached with every object which you will not use. Bad Deal. Thirdly - when expanding object with all the relationships they have with other objects takes time and as we said the caches for the objects would be huge if you did that, you are using cache very ineffectively. Fourth reason for such a design is that large objects in cache are going to kill performance almost up to a level that it will be as slow as querying things from the database anyway! Fifth: Expanding objects takes time, both for the database and for QCubed. If you noticed the drawbacks we talked about till now, think of how worse it would become if QCubed were to cache everything in a nested query. Sixth: QCubed supports another cache called QCache​ for queries that take a lot of time and uses the disk cache but would still save a lot of time for costly queries.

For the above mentioned reasons, the caching system in QCubed is single object based. It allows you to query the database to load a particular row from a table using the primary key and the next time you query for the same object, the object is already there in the cache (depending on how much the cache was full). This might not help for pages which are created using a heavy nested query, but those pages which are designed to show data of single objects (like a page which shows the product details of a single product) can achieve significant performance gain with QCubed's internal caching system. If you want to have a caching system which allows you to cache the results of a heavy query, look into the QCache department! Also, QCubed caching system does not store the data fetched from the database into the cache. It stores the PHP objects that are created after fetching the data. This saves the time even more!

Memcached

For the time being, QCubed only supports memcached as the cache. If you have memcached installed on your server, change the configuration in configuration.inc.php and you would be ready to go! That said, it does not mean that QCubed cannot use other cache providers. The caching system in QCubed is designed in a way that you can add any cache with a PHP interface which can store PHP Objects (Predis library for the redis key value store as of this writing this article is incapable of doing that). For the time being, QCubed uses the 'memcache' PHP extension out of the two available extensions - memcache and memcached. If you are confused about the difference, please read the documentation on the PHP site. Since memcache is one of the most popular caching solutions used by a lot of websites, the caching system was designed to make sure that it utilizes memcached in the best possible way. It is one the resons that QCubed uses a single object based caching system!

​How to use QCubed's caching system

To use QCubed's caching system, you need not out too much efforts. Just install the memcached server, the memcache​ PHP extension and enter the details of the memcache connection parameters in the configuration.inc.php. After this, do a code generation! Your caching system would be ready! Isn't that simple. If you are going to ask how​ and why and ​what if​ then please read the source yourself! It is open source, after all!

Add new comment

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.
  • Allowed HTML tags: <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>