
Вторая часть перевода одной из частей книги «Surviving The Deep End». Первая часть перевода здесь. Эта часть ответит на вопросы:
- Как выявить точные причины низкой производительности?
- Профилирование кода
- Анализ операций с БД
Точное определение причин низкой производительности
Вместо того, чтобы браться оптимизировать случайно выбранные участки кода ,скрестив пальцы на счастье, есть реально действенные методы определения существующих проблем с производительностью. Вот несколько из них.
Профилирование кода
Выполняя нагрузочное тестирование и мониторинга, при этом, расходуемых ресурсов на различных этапах исполнения Вашего приложения Вы сможете увидеть, что различные участки Ваше приложение выполняет хуже или лучше. Однако, обнаружив "слабое место" Вам необходимо тщательно исследовать всю цепочку вызовов методов, которое производит приложение во время работы конкретной страницы. Только анализируя потребляемые ресурсы при исполнении кода, временные затраты Вы сможете определить действительные причины проблемы.
Используя профилирование кода и анализируя время исполнения различных участков кода при исполнении какого-то большого запроса, Вы можете полностью увидеть всю картину потребления памяти, время исполнения, количество вызовов функций и другую подобную информацию. Это просто не заменимо при оптимизации кода.
Одним из самых популярных PHP дебаггеров является XDebug, выполненный в виде расширения Derick'a Rethans'a. xDebug предоставляет возможности отладки, профилирования, а также исследования кода. Профайлер генерирует данные совместимые с cachegrind, которые могут быть проанализированы одной из программ, таких как KCacheGrind (KDE), WinCacheGrind (Win32) или же веб-приложением WebGrind.
В зависимости от приложения, которое Вы выберете для просмотра данных отчетов, поменяются только способы просмотра информации. В любом случае Вы сможете оценить работу своего кода и провести оптимизирующие улучшения.
Текущая версия доступна из PECL и установить Вы ее можете таким способом:
Данная команда скачает и скомпилирует xDebug. ПО для Windows Вы всегда можете скачать на страницах официального сайта проекта.
Для завершения инсталляции необходимо сконфигурировать xDebug, прописав в php.ini настройки. Также надо побеспокоится о замене ранее предустановленных значений опций zend_extension или zend_extension_ts. Вот пример конфигурации для Ubuntu:
Если Вы хотите начать отладку уберите точку с запятой в третьей строке. Профайлер необходимо выключать, если он Вам не нужен т.к. Вы просто заполните отчетами свободное место в системе.

Пример отображения данных в webgrind
Инсталляция WebGrind довольно проста, требуется скопировать исходные файлы проекта на веб-сервер как обычный веб-проект и настроить нужные пути в файлах конфигурации.
Подключив профилирование кода к Вашему приложению Вы без проблем сможете увидеть узкие места системы и отметить участки кода, требующие оптимизации. Вы можете заметить, что Zend Framework приложении около 25% времени выполнения кода забирает Zend_Loader. Конечно, 25% это довольно много и на это стоит обратить внимание.
Анализ операций с БД
xDebug конечно отлично помогает в выявлении возможностей для оптимизации кода, но есть и другие возможности, как например, оптимизация работы приложения с базой данных.
Подключение к БД тянет за собой несколько проблем. Изначально, работа с БД является ресурсоемкой функциональностью. Вашему приложению необходимо подключится к БД, отправить запрос, дождаться его выполнения, прочитать результаты и сделать еще парочку интересных операций... на самом деле все это избыточно! Практически в любом приложении работа с БД будет самым узким местом его работы.
Рассмотрение выгоды оптимизации работы с БД будет зависеть от способа ее использования, в случае з Zend Framework это Zend_Db_Table и Ваши модели, а также от сложности выполнения и обработки SQL запросов, величины извлекаемых данных.
Почти во всех случаях ситуацию может спасти кэширование редко изменяемых, особенно при работе с более серьезными объемами данных, работа с которыми является требовательной по ресурсам и времени. Зачем же извлекать постоянно данные из БД, которые меняются раз в пару часов, дней или даже недель? Кэшируйте такие данные! Лучше всего кэшировать в память с помощью APC или Memcached, конечно файловый кэш тоже подойдет, если ресурсы памяти ограничены, но он не настолько быстрый. Задайте время хранения кэша или же очищайте его, когда данные меняются. Zend_Cache организовывает этот процесс как прогулку в парке - все очень легко. Вот пример, в котором простая модель Comments настроена на кэширование через ini файл:
Когда данные меняются очень часто, то кэширование даст мало пользы.Кэш просто может стать устаревшим, даже когда Zend_Cache еще не завершил его сохранение. В таком случае Вам необходимо отказаться от Zend_Db_Table и воспользоваться более прямым SQL запросом, возможно реорганизовав его, дабы эта операция выполнялась максимально быстрее. Там где извлекаются большие объемы данных убедитесь, что в результатах нету лишних данных. Обратите внимание на используемые поля. Не извлекайте значения из БД полей, которых Вы не используете. Это создаст лишь лишнюю нагрузку и потянет больше ресурсов.
Первое, на что стоит обратить особое внимание, это на MySQL Slow Query Log. Эта фича дает Вам возможность задать время в секундах для запросов и если запрос будет исполняться дольше этого значения, то он будет отнесен к медленным запросам. Все медленные запросы могут быть залогированны для дальнейшего исследования. Использование данного лога повышает нагрузку на сервер, поэтому его рекомендуется включать только на девел машине.
Zend Framework предоставляет свои возможности для исследования запросов и отбора медленных запросов с помощью Zend_Db_Profiler. Он может быть включен, если при инициализации адаптера БД указать опцию 'profiler' => true. После этого Вы можете использовать множество функций профайлера для подсчета количества запросов, общее время выполнения запросов, также есть возможность получить информацию по каждому запросу, что просто необходимо для более глубокого исследования системы. Также есть Zend_Db_Profiler_Firebug, с помощью которого Вы сможете просматривать данную информацию на лету, прямо в Firebug.
Продолжение следует...
Предыдущие части:
- Первая часть
- Вторая часть
- Третья часть
- Четвертая часть
- Пятая часть
