Добрый день всем. Столкнулся с неожиданной проблемой.
Есть сервис, работающий через Doctrine с БД MariaDB. Насколько я знаю, Doctrine для оптимизации работы иногда использует proxy-классы, чтобы не загружать данные, которые вроде как пользователю не требуются. К таким данным могут относиться связанные сущности — пока пользователь непосредственно не обратится к этой связи (а может вообще не обратится), Doctrine может не загружать для нее данные. Обратной стороной такой оптимизации может являться огромное количество запросов в БД для загрузки единственной сущности, если мы работаем сразу с большим набором сущностей. Например, если я беру сущность типа Книга, у которой есть связь типа Автор, то при поочередной обработке массива Книг, мы можем получить множество запросов к сущности Автор, особенно, если авторов очень много. По идее каждый такой запрос должен приводить к увеличению времени выполнения скрипта. Соответственно, кажется разумным заставить Doctrine загрузить сразу все необходимые сущности, а затем просто при необходимости брать их из своего хранилища. Так мы кучу запросов отдельных сущностей можем свести к одному.
Но я столкнулся с неожиданной проблемой. Я сделал предзагрузку единым запросом тех данных, которые, ожидаемо, скорее всего потребуются. И сравнил лог запросов к БД до и после подобной оптимизации. Лог показал сокращение числа запросов в среднем процентов на 15. Вроде всё гуд. Но вот только со временем выполнения скрипта случилась какая-то чехарда. Я беру две сущности, сопоставимые по своим параметрам и связям и получаю, что по одной из них все отдельные операции в среднем выполняются втрое дольше! Я прогнал тест несколько раз и всегда идентичный результат — время выполнения отдельных мелких операций примерно утроено. В итоге я решил отключить предзагрузку. Лог запросов вырос обратно, но зато время выполнения уменьшилось для обеих проверяемых сущностей и стало примерно одинаковым (в первом случае, напомню, оно отличалось в три раза). Почему такое могло случиться?
А какие запросы доктрина для жадности генерирует? С join-ом или в два запроса?