Reputation: 1231
I am starting to dip my first fingers in Yii2 framework. When querying for data with ActiveRecord I want to use query caching. I query like this:
$BestCustomers = SaleOrder::getDb()->cache(function ($db) {
return SaleOrder::find()
->with(['preOrder', 'invoice', 'articlesOut', 'articlesOut.product'])
->limit(8)->all();
});
Seems to work, but how to know if its really getting data from cache instead of Database?
From performance side I dont see any major changes, thats why im conserned if it is really working.
Upvotes: 1
Views: 6179
Reputation: 121
Another option would be to add the yii2-debug extension to show the excellent debug toolbar on your site. If you correctly installed and configured the extension, you should see a "toolbar" at the bottom of your Yii2 site. You may need to click it to expand it. Look for the "DB" section to see exactly what queries were run for a given call. If you cache is working correctly, you will only see a given query during the initial page load (before the value has been cached) - subsequent loads should no longer show the query being run.
Upvotes: 0
Reputation: 1296
You have several options. The code within your callable is only executed when the data is refetched. Therefore if you write a log-entry or set a breakpoint in there, you will know when data is loaded from your DB. You can also truncate your cache, reload the page and compare the filesize (FileCache) or the db-entries of your cache-table (DB Cache). This all depends on your cache config.
If you want to be more specific about when to load data, how long your cache is valid and what it depends upon, have a look at the params of the cache-function. You find the code with doc here. Simply set a dependency and you're good.
Two parts are involved here. First configure your cache component to use one of Yii2s several options. This is done within the config-file in the cache
-section. The most common ones are the file- and db-cache.
'cache'=>[
'class'=>'yii\caching\DbCache',
],
If you want to use the DB-cache you first have to apply a migration creating your cache-table. You can find the migration in the yii-folder under vendor\yiisoft\yii2\caching\migrations
. If you use the file cache, this step is not needed.
Next you want to make sure your DB-component is configured the right way. There are several properties relevant for caching. The most important ones being enableSchemaCache
and enableQueryCache
. Especially the first of the two has a massive impact on performance. It's a good idea to set both of those depending on your debug-status. Here's an example how I tend to configure a db-connection for caching:
return [
'class'=>'yii\db\Connection',
'dsn'=>'mysql:host=localhost;dbname=xxxxx-local',
'username'=>'root',
'password'=>'',
'charset'=>'utf8',
'enableSchemaCache'=>!YII_DEBUG,
'schemaCacheDuration'=>3600,
'schemaCache'=>'cache',
'enableQueryCache'=>!YII_DEBUG,
'queryCacheDuration'=>3600,
];
This method I use within an action to flush my cache application side. You want to do this after a db-migration to assert the new schema gets recached.
protected function flushCache($id='cache')
{
if (!isset(Yii::$app->{$id}) || !(Yii::$app->{$id} instanceof Cache)) {
$msg = Yii::t('Invalid cache to flush: {cache}', ['cache'=>$id]);
throw new InvalidParamException($msg);
}
/* @var $cache \yii\caching\Cache */
$cache = Yii::$app->{$id};
if ($cache->flush()) {
$msg = Yii::t('app', 'Successfully flushed cache `{cache}`', ['cache'=>$id]);
Yii::$app->session->setFlash('success', $msg);
} else {
$msg = Yii::t('app', 'Problem while flushing cache `{cache}`', ['cache'=>$id]);
Yii::$app->session->setFlash('danger', $msg);
}
}
Upvotes: 5