Страница 1 из 1

Глобальный runtime кеш AR моделей

Добавлено: 2013.09.23, 11:28
thekip
Задался таким вопросом, существует ли реализация рантайм кеша моделей, и если не существует, то почему бы её не внедрить.
Когда мы используем реляционные связи в ActiveRecord, иногда получается так, что выполняются лишние запросы, для уже ранее полученных моделей в пределах одного запроса страницы.

Например у меня есть модель новости (NewsModel), и модель комментарии (CommentsModel). У обоих из этих моделей, есть реляционная связь (BelongsTo), скажем CreateUser.

На странице я вывожу текст новости, под ней мета информацию, в т.ч. автора статьи ($news->createUser->name), затем идут комментарии, где возле каждого комментария выводится его автор ($comments->createUser->name).
К этой новости, кроме пользователей, оставляет комментарии так же и сам автор статьи.

Предположим по какой то причине я не захотел использовать with(), что бы выбрать всех комментаторов сразу с их комментариями (пример чисто синтетический). Получится что у нас будет 2 и более запроса к базе за одной и той же моделью автора новости. Первый раз когда мы покажем автора новости, и в следующий раз когда будем выводить его же комментарии.

Глобальный кеш предполагает что все модели, имеют некий идентификатор, например primaryKey, и при выполнении реляционного запроса система прежде проверяет нет ли уже в глобальном кеше такого id, и если есть, то возвращает оттуда.

Разумеется не все так просто. Иногда в реляционных запросах присутсвуют дополнительные параметры, поэтому в качестве id модели, можно использовать хеш от сериализованного объекта CdbCriteria.

Так же могут возникнуть плавающие глюки, связанные с тем что в рамках одного запроса страницы, мы можем сначала изменить модель, а затем её вывести. В таком случае лучше всего обнулять её в глобальном кеше сразу после сохранения изменений. Может показаться, что обнуление модели в кеше не обязательная процедура, т.к. все объекты передаются по ссылке и изменения сразу отобразятся и в кеше, но это не всегда так. Такой подход не сработает в случае если в качестве значения одного из свойств будет присвоено что ни будь типа new CdbExpression("NOW()").

В реальном проекте такой кеш может сократить количество ненужных запросов, которые очень сложно вынести на отдельный уровень абстракции и поможет избежать сквозного кода.

Re: Глобальный runtime кеш AR моделей

Добавлено: 2013.09.23, 11:44
samdark
Пробовали это сделать и применить в реальном проекте. Огребли багов по полной программе из за залипания моделей и различий параметров. При этом значимого выигрыша в производительности нет.

Re: Глобальный runtime кеш AR моделей

Добавлено: 2013.09.23, 11:55
thekip
Залипание моделей, это типа когда она по каким то причинам не обновилась до актуального состояния?

Re: Глобальный runtime кеш AR моделей

Добавлено: 2013.09.23, 15:28
samdark
Да.

Re: Глобальный runtime кеш AR моделей

Добавлено: 2013.09.29, 13:39
Ekstazi
Полностью согласен с Александром, тоже пробовали и пришли к тому же мнению. Слишком сложна реализация и плюсов мало.