Memcache с Symfony / Doctrine перезагружает данные - PullRequest
3 голосов
/ 02 марта 2011

В моем проекте Symfony у меня есть «сложный» запрос, который выглядит так:

$d = Doctrine_Core::getTable('MAIN_TABLE')
    // Create the base query with some keywords
->luceneSearch($keywords)
->innerJoin('w.T1 ws')
->innerJoin('ws.T2 s')
    ->innerJoin('w.T3 piv')
->innerJoin('piv.T4 per')
->innerJoin('w.T5 st')
    ...
->innerJoin('doc.T12 docT')
->innerJoin('w.Lang lng')
->execute();

Я добавил все эти innerJoin, чтобы уменьшить количество запросов из-за моей модели данных. Фактически все данные восстанавливаются с помощью этого единственного запроса .... но запрос занял от 2 до 20 секунд. зависит от ключевых слов.

Я решил использовать memcache, потому что данные не меняются все время.

Что я сделал, так это сконфигурировал memcache и добавил

...
->useResultCache(true)
->execute();

на мой запрос.

Что странно в том, что:

  • В первый раз (когда кэш пуст / очищен) выполняется только один запрос
  • Во второй раз выполняется ~ 130 боров, и это занимает больше времени, чем в первом ...

Эти «новые» запросы извлекают данные из «внутреннего соединения» для каждой записи.

Что я не понимаю, так это то, почему «внутренние» данные не сохраняются в кеше?

Я пытался изменить режим гидратации, но он, кажется, не влияет.

У кого-то есть идея?

1 Ответ

1 голос
/ 17 марта 2011

После целого дня поисков в Google, анализа доктрины и отчаяния я нашел статью, объясняющую решение:

class User extends BaseUser{
    public function serializeReferences($bool=null)
    {
        return true;
    }
}

Проблема заключалась в том, что объект профиля не сохранялся в кеше результатов и, таким образом, вызывал запрос каждый раз, когда он вызывался из объекта пользователя. После долгой охоты, долгого времени в #doctrine и нескольких отрядов от пары человек, оказывается, по умолчанию Doctrine только сериализует непосредственное отношение к основному объекту. Тем не менее, вы можете сделать так, чтобы он последовательно сериализировал объекты, переопределяя функцию serializeReferences и возвращая true в классе, из которого вы хотите сериализовать ссылки. В моем примере это класс User. Поскольку нашему приложению никогда не потребуется сериализация класса «User» только в кеше результатов, я полностью переопределил функцию и сделал так, чтобы она всегда возвращала true

http://shout.setfive.com/2010/04/28/using-doctrine-result-cache-with-two-deep-relations/

...