1) Переключаем дебагер в local.php, потому что yii2Debug почему-то не хочет показывать информацию по запросам. И контролируем, чтобы профайлинг и отслеживание параметров было включено в компоненте db.

return [
  'components' => [
    'db' => [
      'enableProfiling' => true,
      'enableParamLogging' => true,
    ],
    'yii2Debug' => [
      'enabled' => false,
    ],
    'log' => [
    'routes' => [
      'YiiDebugToolbarRoute' => [
        'enabled' => YII_DEBUG,
        'class' => 'ygin.ext.yii-debug-toolbar.YiiDebugToolbarRoute’,
      ],
    ],
  ],
]

Смотрим на количество запросов. С выключенным кешем их много, с включённым - их должно быть в разы меньше.

Включение кеша происходит так:

'cache' => array(
  'class' => 'system.caching.CFileCache',
  //'class' => 'system.caching.CDummyCache',
),

При нажатии на SQL в дебаг-панели можем увидеть список выполняющихся запросов при генерации страницы. Нужно проконтролировать, чтобы не было лишних запросов.

2) В модели заводим 2 даты: дату создания и дату изменения

Например, в объекте News создаём свойства date_create и date_update (оба обязательные).

В модели добавляем поведение, которое будет автоматически изменять эти даты:

public function behaviors(){
  return array(
    'CTimestampBehavior' => array(
      'class' => 'zii.behaviors.CTimestampBehavior',
      'createAttribute' => 'date_create',
      'updateAttribute' => 'date_update',
      ‘setUpdateOnCreate’ => true,
    )
  );
}

3) Делаем кеширование результатов выполнения запроса к базе

Перед всеми методами получения данных в контроллере find, findByParameters, findByPk и т.д. кешируем:

$dependency = new CDbCacheDependency('
  SELECT MAX(r.date_update) FROM (
    SELECT MAX(p.date_update) as date_update FROM pr_news p
    UNION
    SELECT MAX(c.date_update) as date_update FROM pr_news_category c
  ) r
');


$newsList = News::model()->cache(
  3600*24*365, // Очень большое число, чтобы кеш не зависел от времени
  $dependency
)->with(‘news_category’)->findByParams(...);

или так:

$dependency = new CDbCacheDependency('
  SELECT MAX(p.date_update) as date_update FROM pr_news p
');

$newsList = News::model()->cache(
  3600*24*365, // Очень большое число, чтобы кеш не зависел от времени
  $dependency
)->findByParams(...);

По сути подменяем тяжёлый запрос выборки новостей на лёгкий и быстрый запрос получения максимальной даты изменения.

4) Тегированный COutputCache

В /protected/config/project.php

'behaviors' => array(
    'startUpBehavior' => array(
      'class' => 'application.components.StartUpBehavior',
    ),
),
'import' => array(
  'application.components.cache.*',
),

Чтобы правильно дописать varyByParam, нужно посмотреть на Get-параметры соответствующего экшена в контроллере. 'COutputCache + index' означает, что смотрим на гет-параметры actionIndex (в том числе в правила $_urlRules модуля).

В контроллер:

public function filters(){
$filters = []; $filters[] = array( 'COutputCache + index', 'varyByParam' => array( 'alias', 'page', ), // 'varyBySession' => true, // 'varyByExpression' => 'Yii::app()->user->getId()', 'duration' => $this->module->listCacheExpire, 'dependency' => new CacheTagDependency(CacheTag::INTERVIEW), ); $filters [] = array( 'COutputCache + view', 'varyByParam' => array( 'alias', 'id' ), 'duration' => $this->module->viewCacheExpire, 'dependency' => new CacheTagDependency(
CacheTag::INTERVIEW), ); return $filters; }

В модель:

protected function afterSave() {
  parent::afterSave();
  self::clearCache();
}

protected function afterDelete() {
  parent::afterDelete();
  self::clearCache();
}

public static function clearCache() {
  Yii::app()->cache->clear(CacheTag::INFOGRAFIKA);
}

В модуль:

class PNewsModule extends NewsModule {
  public $listCacheExpire = 30000000;
  public $viewCacheExpire = 30000000;

6) Делаем в представлении обёртку, внутри которой всё кешируется

Если не понимаете зачем, применять это не нужно, т.к. скорее всего Тегированный COutputCache уже всё закешировал.

if ($this->beginCache( __FILE__.__LINE__.'_'.$model->primaryKey , array(
  'dependency'=> array(
  'class' => 'system.caching.dependencies.CDbCacheDependency',
  'sql' => 'SELECT MAX(r.date_update) FROM (
      SELECT MAX(p.date_update) as date_update FROM pr_news p
      UNION
      SELECT MAX(c.date_update) as date_update FROM pr_news_category c
    ) r',
  ),
  'duration' => 3600*24*365, // Очень большое число, чтобы кеш не зависел от времени
  'varyByParam' => array('page'), // Гет-параметры (например, пагинация)
))) {

код

    $this->endCache();
    if (YII_DEBUG) {
      echo "Страница НЕ из кеша";
    }
} else {
    if (YII_DEBUG){
echo "Страница из кеша";
}
}

7) Динамические блоки кешируем через renderDynamic

Например, комментарии в закешированных Новостях.

Yii::app()->controller->renderDynamic('widget', 'ygin.modules.comments.widgets.ECommentsListWidget',
  [
    'model' => $newsItem,
  ], true);

8) Для более подробного изучения кеширования в Yii:

http://www.yiiframework.com/doc/guide/1.1/ru/caching.overview

19 сентября 2016

Комментарии (0)

Добавить комментарий