Не так давно я работал над оптимизацией и рефакторингом доставшегося нам по наследству проекта. Проблема была в том, что для карты на главной странице компании грузились через AJAX и генерация страниц даже на продакшен-сервере происходила 2-3 секунды, а у меня на рабочей машине и все 10.

По своему опыту я сразу стал смотреть лог и искать запросы для этой страницы, обычно все дело в них. Например, если где-то не проставлены индексы или просто сам запрос написан криво.

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

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

Долго думал почему в Symfony-приложении запрос выполняется несколько секунд, а напрямую в базе моментально. Ответ оказался довольно очевиден.

Изначальный запрос


$qb = $this->createQueryBuilder('company')
->select('company, csp, fb, d, csp_type, csp_sub_type, additional_services, cwt')
->leftJoin('company.specializations', 'csp')
->leftJoin('csp.type', 'csp_type')
->leftJoin('csp.subType', 'csp_sub_type')
->leftJoin('company.feedbacks', 'fb')
->leftJoin('company.deals', 'd')
->leftJoin('company.additionalServices', 'additional_services')
->leftJoin('company.workingTime', 'cwt')
->where('company.id IN(:ids)')
->setParameter('ids', $ids)
;

Конечный


$qb = $this->createQueryBuilder('company')
->select('company.id, company.name, company.gps, company.vip, IDENTITY(company.type) as type')
->where('company.id IN(:ids)')
->setParameter('ids', $ids)
;

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

Я думаю, что для большинства эта заметка будет очевидна, но пусть она будет хорошим напоминанием о том как делать не надо.