I’ve been searching for answers to some questions I have on APC Caching specifically related to CActiveRecord but was unable to find anything that really helped. What I found seemed murky, and there are a number of unanswered cries for help in this forum regarding this subject. Therefore I thought that it might be time to start up some discussions and clarify the mysteries.
What initiated my quest was my desire to do some query caching. I wanted to use APC, as all-around, it seemed to have the claims of best performance (when configured correctly). It looked straightforward enough at the start and I really didn’t have much trouble installing it on my VM (VirtualBox with Ubuntu 12.04). But then I became confused when I used the cache() method for a findAll query: the results were cached with no problem and they were retrieved with no problem, but then I got into using the dependency with no luck. Finally frustrated, I decided I would handle the caching myself using CApcCache’s get and set. Lo and behold, the query continued to be cached even though I removed the cache() method! So if I may, I would like to start the discussion with this:
This resulted in findAll getting cached by default, unless I added cached(0) to disable it. But I didn’t want to do that throughout the rest of the code as that would return stale data where it shouldn’t. I couldn’t find documentation as to why this was happening, then realized that is likely setting it as the default for the system. So I did this:
Voila! No more default caching and I could set and get what I wanted. I want to do more with this, however, perhaps some settings where some models will cache as the data may not change for long periods of time, but am a little stumped on how to progress. I was trying to override the cache() to use CApcCache and was only able to save to the cache and not serve from it.
I would love some input and I will add as much as I have figured out thus far and figure out as I work through my project.
Yes, the management of the dependency is the key point in using cache.
You’d better go back to that point, discarding all the changes made after that. Don’t try to call ‘get’ and ‘set’ of CApcCache for query caching by yourself.
IMHO, what you have to do is just to understand how to work with cache dependency.
I agree, I did some testing with caching pages and used the dependency just fine it that instance. I must have been doing something wrong with the query caching. I’d like to ask this: Will the findAll query cache by default with the caching component in place?
By default, db connection component uses ‘cache’ component when it caches the query result.
It means that it uses the cache component whose name is ‘cache’. So when you use APC cache component with the name of ‘apcCache’ or something, then query cache doesn’t use APC. But if you have another cache component whose name is ‘cache’, then it will be used for the query caching.
And you can change it by setting the ‘queryCacheID’ property of the db component.
The query caching is a kind of data cache, and is performed in the level of db connection. It uses the SQL text (actually the hash of it) as the key to the cache entry. So when you execute the same SQL next time, it may be served from the cache, only if it’s not expired and the dependencies are not changed.
CActiveRecord::cache() method is a kind of utility function to call it.
One thing you may note is that you would be better clear the cache entries (especially "User Cache Entries") of APC every time when you want to test something new, in order to avoid strange results caused by the previously cached entries.
Here’s a question about the frequency of a CDbCacheDependency check: Any time the cache is being checked and the hash matches, the dependency needs to be checked too. So that means there’s a DB hit for that SQL dependency every time, which I want to avoid for this specific instance. Does the duration take precedence over the dependency? If I set a duration of 3600 seconds, then the dependency will not be tested until the duration has expired. Is that correct?
Without calling the cache() method, it’s saving and serving from the cache. That should not be happening as far as I understand. It’s not supposed to be caching by default. I realize, of course, I could use cache(0), but that’s troublesome to do that for every query. I would rather specify using the cache rather than as a default.
That is my understanding, too, but the caching I was seeing was of the ‘saving’ and ‘serving’ variety, as I am currently not caching the schema. Bears a little looking into. Thanks for your help, softark!