Кэширование схем в Yii
Включив кэширование в приложении Yii я ожидал увидеть уменьшение количества запросов в БД. Нет, не получилось. Нужно настраивать кэш перед каждым запросом в базу данных.
Вот так указывается, что результат следующего простого запроса SQL должен быть помещён в кэш на 300 секунд.
<?php $cmd = Yii::app()->db->cache(300)->createCommand("SELECT * FROM albums LIMIT 0, 30"); $albums = $cmd->queryAll();
Аналогично при использовании механизма Active Record:
<?php $albums = Albums::model()->cache(300)->limit(30)->queryAll();
Подробнее об этом в официальной документации Yii framework.
Но если посмотреть в отладочные протоколы, то видно, что перед запросом через Active Record делается запрос на получение структуры таблицы.
SHOW FULL COLUMNS FROM `albums` SHOW CREATE TABLE `albums`
И хотя инструкция по улучшению производительности рекомендует не пользоваться Active Record, от этих запросов можно избавиться. Нужно включить кэширование схем данных.
Как избавиться от запросов SHOW CREATE TABLE
Для включения кэширования схем данных нужно в настройках приложения указать время хранения схемы
'db'=> array( // ... настройки подключения // Enabling Table Schema Caching (Disable SHOW CREATE TABLE) / Кеширование схем данных 'schemaCachingDuration' => 3600, ),
Теперь описания таблиц, обращение к которым выполняется через Active Record, будет храниться в кэше один час.
Обновление кэша схем при изменении таблиц
При изменении таблиц нужно удалить старые описания схем из кэша. Самый простой способ: очистка всего кэша.
<?php // Clear all cache / Очистить весь кэш Yii::app()->cache->flush();
Но это очень непроизводительно, потому что из кэша удалятся вообще все данные.
Лучше удалить из кэша схему одной таблицы отдельной командой
<?php // Clear or Refresh Table Schema Cache For One Table / Очистка из кэша схемы одной таблицы Yii::app()->db->schema->getTable('albums', true);
Если нужно удалить описания всех известных таблиц, то есть встроенный механизм обновления, который удаляет описания всех известных таблиц, а для этого их сначала нужно загрузить из базы данных.
<?php // Clear or Refresh All Table Schema Cache / Удаление из кэша схем всех таблиц // Load all tables of the application in the schema / Загрузить описание всех таблиц Yii::app()->db->schema->getTables(); // Сlear the cache of all loaded tables / Удаление из кэша описаний всех загруженных таблиц Yii::app()->db->schema->refresh();
При использовании механизма миграций есть возможность очистить кэш схемы одной таблицы
<?php /** * Пример файла миграции, изменяющего таблицу albums */ class m140318_185558_albums_artist extends CDbMigration { public function up() { $this->addColumn('albums', 'artist', 'VARCHAR(255) DEFAULT NULL COMMENT \'Имя исполнителя\''); // ... другие команды // Refresh table schema cache for one table / Обновление в кэше описания схемы одной таблицы $this->refreshTableSchema('albums'); } }
Если нужно очистить информацию о всех схемах, можно воспользоваться вот таким классом DbMigration
<?php /** * /protected/components/DbMigration */ /** * Class DbMigration * * Класс компоненты миграций, расширяющий работу с кэшем описаний схем всех таблиц */ class DbMigration extends CDbMigration { /** * Refresh all tables schemas cache / Обновление в кэше описаний схем всех таблиц */ public function refreshTableSchemas() { echo " > refresh all tables schemas cache ..."; $time=microtime(true); Yii::app()->db->schema->getTables(); // load all tables Yii::app()->db->schema->refresh(); // remove all loaded from cache Yii::app()->db->schema->getTables(); // load all tables again and store into cache echo " done (time: ".sprintf('%.3f', microtime(true)-$time)."s)\n"; } }
Полезные ссылки:
* средство отладки приложений yii-debug-panel
* Улучшение производительности в приложениях на базе фреймворка Yii
* механизм миграций в Yii