"Сериализация" объекта XPDOQuery
Как оказалось, у меня только лишь подготовка объекта XPDOQuery (создание, подключение TV, условия) занимает 0.1 сек. И это без выполнения запроса.
TV и условий там много. Именно поэтому, и набегает столько времени. Логично здесь реализовать кэширование этого объекта. Но проблема в том, что этот объект НЕсериализуем.
.
Кэширование результата выполнения запроса выполняет MySQL (да и самому можно сделать кэширование результирующего массива данных без запроса к БД). Но проблема в том, что запросы каждый раз разные и отличаются совсем чуть-чуть (например, с разными LIMIT и OFFSET при пагинации). Т.е. каждый раз при загрузке нового page'а уходит 0.1 сек на подготовку xpdo (а именно — подключение ряда TV и условий — тех же самых).
Как можно запомнить состояние объекта XPDOQuery для его последующего быстрого восстановления?
TV и условий там много. Именно поэтому, и набегает столько времени. Логично здесь реализовать кэширование этого объекта. Но проблема в том, что этот объект НЕсериализуем.
.
Кэширование результата выполнения запроса выполняет MySQL (да и самому можно сделать кэширование результирующего массива данных без запроса к БД). Но проблема в том, что запросы каждый раз разные и отличаются совсем чуть-чуть (например, с разными LIMIT и OFFSET при пагинации). Т.е. каждый раз при загрузке нового page'а уходит 0.1 сек на подготовку xpdo (а именно — подключение ряда TV и условий — тех же самых).
Как можно запомнить состояние объекта XPDOQuery для его последующего быстрого восстановления?
Комментарии: 2
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
xPDOQuery_mysql extends xPDOQuery extends xPDOCriteria
Самый простой вариант — засериализовать все поля объекта xPDOQuery_mySQL. Проблема в том, что открытыми являются только поля класса xPDOCriteria:
Собственные же поля класса xPDOQuery являются защищёнными.
Соответственно, единственным способом вручную засериализовать поля объекта xPDOQuery (xPDOQuery_mysql) остаётся наследование. Что-то вроде такого:
Но в этом случае также потребуется заставить метод xpdo->newQuery вместо xPDOQuery_mysql создавать объект класса xPDOQueryManager_mysql. Опять-таки заставить можно, только перегрузив класс modx и метод newQuery. И это не всё. Нужно ещё заставить modx в процессе инициализации вместо modx использовать перегруженный класс modxManager. Но это уже попахивает извращением.
В голову лезет ещё вариант с reflection. Может, к утру что-нибудь придумаю…
Далее в коде делаем так (кэшируем состояние объекта xPDOQuery):
Тест (1 TV и 2 простых условия):
При первом выполнении (запрос строится с нуля): 0.005-0.007 сек
При последующих выполнениях (объект xPDOQuery восстанавливается из файлового кэша): 0.0007 сек (из них 0.0005 сек — чтение кэш-файла с состоянием xPDOQuery)
Разница: в 7-10 раз. И это только на простом запросе (1 tv и 2 условия).
Мой запрос с 30 tv-ками и кучей сложных условий готовится (без выполнения) 0.1 сек.
С кэшированием запроса вплоть до пагинации (до добавления limit/offset) — 0.0007-0.0010 сек
Разница: в 70-100 раз.
P.S. Кэширование запроса xPDOQuery совместно с его выполнением в режиме pdo может придать ему реактивные свойства. И переписывать запрос на чистый pdo не потребуется.