Задался таким вопросом, существует ли реализация рантайм кеша моделей, и если не существует, то почему бы её не внедрить.
Когда мы используем реляционные связи в ActiveRecord, иногда получается так, что выполняются лишние запросы, для уже ранее полученных моделей в пределах одного запроса страницы.
Например у меня есть модель новости (NewsModel), и модель комментарии (CommentsModel). У обоих из этих моделей, есть реляционная связь (BelongsTo), скажем CreateUser.
На странице я вывожу текст новости, под ней мета информацию, в т.ч. автора статьи ($news->createUser->name), затем идут комментарии, где возле каждого комментария выводится его автор ($comments->createUser->name).
К этой новости, кроме пользователей, оставляет комментарии так же и сам автор статьи.
Предположим по какой то причине я не захотел использовать with(), что бы выбрать всех комментаторов сразу с их комментариями (пример чисто синтетический). Получится что у нас будет 2 и более запроса к базе за одной и той же моделью автора новости. Первый раз когда мы покажем автора новости, и в следующий раз когда будем выводить его же комментарии.
Глобальный кеш предполагает что все модели, имеют некий идентификатор, например primaryKey, и при выполнении реляционного запроса система прежде проверяет нет ли уже в глобальном кеше такого id, и если есть, то возвращает оттуда.
Разумеется не все так просто. Иногда в реляционных запросах присутсвуют дополнительные параметры, поэтому в качестве id модели, можно использовать хеш от сериализованного объекта CdbCriteria.
Так же могут возникнуть плавающие глюки, связанные с тем что в рамках одного запроса страницы, мы можем сначала изменить модель, а затем её вывести. В таком случае лучше всего обнулять её в глобальном кеше сразу после сохранения изменений. Может показаться, что обнуление модели в кеше не обязательная процедура, т.к. все объекты передаются по ссылке и изменения сразу отобразятся и в кеше, но это не всегда так. Такой подход не сработает в случае если в качестве значения одного из свойств будет присвоено что ни будь типа new CdbExpression("NOW()").
В реальном проекте такой кеш может сократить количество ненужных запросов, которые очень сложно вынести на отдельный уровень абстракции и поможет избежать сквозного кода.
Глобальный runtime кеш AR моделей
- samdark
- Администратор
- Сообщения: 9489
- Зарегистрирован: 2009.04.02, 13:46
- Откуда: Воронеж
- Контактная информация:
Re: Глобальный runtime кеш AR моделей
Пробовали это сделать и применить в реальном проекте. Огребли багов по полной программе из за залипания моделей и различий параметров. При этом значимого выигрыша в производительности нет.
Нравится Yii? Давайте сделаем его лучше!.
Re: Глобальный runtime кеш AR моделей
Залипание моделей, это типа когда она по каким то причинам не обновилась до актуального состояния?
-
- Сообщения: 1428
- Зарегистрирован: 2009.08.20, 22:54
- Откуда: Молдова, Бельцы
- Контактная информация:
Re: Глобальный runtime кеш AR моделей
Полностью согласен с Александром, тоже пробовали и пришли к тому же мнению. Слишком сложна реализация и плюсов мало.