Производительность WordPress
Нередко в Сети встречаются высказывания, что WordPress очень "прожорлив" и сильно "грузит" сервер. В качестве "доказательства" приводят количество запросов к базе данных. Действительно, на каждую страницу WordPress может потратить 20-40 запросов к базе данных. Но, является ли это таким важным параметром, как это представляют критики? Попробуем разобраться.
Однако, для того, чтобы оценить производительность WordPress, необходимо для начала понять его алгоритм работы. То есть нужно понять по какой такой причине WordPress создает столько запросов к базе данных и почему (а то критики WordPress утверждают, что некая система X делает "тоже самое" всего за 2-5 запроса)?
Связка PHP и MySQL
Представим себе, что у нас уже есть блог с набором страниц. База данных блога - это библиотека, где книги - это отдельные страницы-записи рассортированые по полкам (рубрикам, авторам и т.д.).
Теперь наша задача получить одну книгу (запись) по какому-то критерию, например названию. Сделать это можно двумя способами.
Первый - мы берем всю библиотеку сразу и получаем отсортированных список всех книг. Этот список мы с помощью PHP пролистываем и проверяем совпадение с нужным названием.
Второй способ работает по другому. Мы просто даем свою заявку библиотекарю, который знает где и что лежит и сразу получаем нужную нам книгу.
Как видите, в первом случае мы вынуждены использовать дополнительное программное время (PHP) на проверку нужного условия, а во втором полностью полагаемся на интеллект библиотекаря (MySQL).
Это упрощенный пример, но он показывает, что можно сделать систему управления сайтом (CMS) "нагружая" либо PHP, либо базу данных (БД).
Оптимальный вариант
Так всё-таки, что лучше: использовать дополнительный запрос к БД или написать дополнительный PHP-код? Ответ очень прост: использовать БД. Почему? Да потому что база данных для этого и предназначена! Что такое база данных? Это специальная программа-драйвер, которая определенным образом хранит, обрабатывает и обновляет данные. Физически данные хранятся в виде файлов, но БД имеет средства получения нужной выборки гораздо быстрее, чем просто считывание этого файла, а потом его обработка. Базы данных обладают различными механизмами, позволяющими сделать выборку практически мгновенно, например за счет индексирования таблиц или кэширования.
Известно, что PHP имеет не самую удачную реализацию функций по работе со строками. Например, таблица опций WordPress (wp_options) может составлять 500-600Кб. Представьте себе, что вам нужно получить каких-либо 20 опций (значений). Если делать это через один запрос (то есть считать весь файл целиком), то на PHP придется перебрать в цикле все 200-300 существующих записей, чтобы создать массив из нужных. При этом будут задействованы медленные функции для строк. Эта же задача с помощью MySQL решается элементарной стандартной выборкой. Правда в этом случае мы создадим дополнительно 20 запросов. Однако и в первом случае, эти же самые запросы, по-сути, будут просто сымитированны, но уже средствами PHP.
Оправдано ли использование базы данных? Да, и на это есть несколько причин. Прежде всего необходимо отметить, что базы данных допускают одновременный доступ сразу множества пользователей. То есть когда вы грузите страничку и получаете выборку, то одновременно с вами это могут сделать десятки, сотни или тысячи посетителей. Встроенные механизмы БД распределяют нагрузку таким образом, чтобы обеспечить собственную работоспособность и не "завалить" сервер. Передавая нагрузку на MySQL мы обеспечиваем и быстрое выполнение PHP-скрипта, таким образом снимая нагрузку на сервер.
Вторым фактором является то, что база данных позволяет делать сложные выборки с использованием разнообразных условий. То есть когда нужно получить только номера последних записей, совершенно не обязательно выполнять запрос и получать все данные, включая текст, название, автора и т.д. Мы просто указываем нужное нам поле (ключ) и получаем уже готовый результат.
Третий фактор - PHP имеет мощную поддержку MySQL. Таким образом отпадает необходимость "изобретать велосипед" - с помощью PHP мы можем не только сформировать нужный запрос к БД, но и получить его в виде, сразу пригодном для обработки или вывода. То есть отпадает необходимость использования медленных функций, сложных циклов и рекурсий.
Сколько нужно запросов?
Возникает резонный вопрос, а зачем WordPress'у столько запросов к базе? Если выводится 10 записей, да список рубрик, то хватит и 15-20. Откуда же берется 30-40? На самом деле здесь нет никакой тайны - множество запросов осуществляется для получения разных настроек, например адрес, название, описание блога, формат даты и т.д.
Всё это конечно же хранится в базе данных, следовательно без дополнительных запросов просто не обойтись. Причем разработчики WordPress применили алгоритмы, позволяющие уменьшить количество запросов, если вы получаете данные с помощью определенных функций, например bloginfo().
Для того, чтобы реально оценить количество запросов к базе данных, а также увидеть что это за запросы, я решил провести небольшое исследование. Мне интересно было узнать реальное количество запросов, оценить эти запросы, а также увидеть количество преданных данных (записей, rows) из БД.
Методика исследования
Для получения нужных данных я использовал программу MySQLAdministrator. Это довольно сложная утилита, которая позволяет не только настроить MySQL, но и получать логи (отчеты).
За основу я взял WordPress 2.0.5 своей сборки. Отключил все плагины, установил стандартный шаблон (default). Пермалинки (ЧПУ, постоянные ссылки) были включены. В качестве тестовой площадки я использовал свой локальный блог и был залогиннен. Количество записей на главной странице - 8.
Количество запросов с кэшем и без
Первым делом я отключил кэш. В этом случае количество запросов составило 40 (это генерация главной страницы). После включения кэша, количество запросов уменьшилось до 15. Это говорит об эффективности использования кэша. Причем размер кэша на диске составил в сумме всего 8Кб.
Что грузим?
Больше всего меня интересовало "качество" запросов. Здесь я привожу список групп запросов. (Кэш отключен).
- Запросы к wp_options (siteurl, home, hack_file, active_plugins, permalink_structure, category_base, date_format, template, wp_user_roles, rewrite_rules, html_type, blog_charset, posts_per_page, gmt_offset, what_to_show, gzipcompression, blogname, stylesheet, kubrick_header_image, kubrick_header_color, kubrick_header_display, blogdescription, use_smilies, links_recently_updated_time).
- Запросы к таблицам пользователей wp_users и wp_usermeta (user_login, meta_key, meta_value).
- Запросы к таблице всех записей wp_posts (вначале выбираются последние 8 записей, после этого получаются категории из wp_post2cat и wp_categories).
- Запросы к данным записей wp_postmeta.
- Запрос на получение всех постоянных записей (полностью все данные).
- Запрос для формирования архива.
- Запрос на формирование списка рубрик.
- Запросы на формирование списка ссылок по категориям.
При включении кэша, количество запросов уменьшилось в основном за счет опций (wp_options).
Оптимизация запросов
Нужно отметить, что запросы на выборку сделаны корректно. Везде где возможно, установлено ограничение на количество записей (LIMIT, DISTINCT) и уточненны условия (WHERE). То есть получаемые данные сразу готовы для PHP-обработки и вывода (собственно это видно по коду самого WordPress).
Объем выборки (rows) не вызывает опасений - лишние записи не берутся из базы данных и не обрабатываются.
Проблемные точки
Однако, это не означает, что у WordPress нет проблем. Самая очевидная из них, это получение всех постоянных страниц (SELECT * FROM wp_posts WHERE post_status = 'static' ORDER BY post_title ASC). Этот запрос означает, что при каждом обновлении будут браться из БД все постоянные страницы со всем полями. Если их много и они большие, то это действительно может привести к существенной нарузке. При этом бессмысленную - нет смысла получать полный текст (а это основной объем). Причем при включенном кэше всё равно происходит повторная выборка.
Итоги
Думаю, что эта статья отчасти развенчает миф о якобы большой нагрузке, создаваемой WordPress'ом. Если посмотреть на возможности WordPress, то становится вполне объяснимым и количество создаваемых запросов к базе данных. Ведь они нужны не просто так, а для обеспечения его функциональности. А если учесть эффективность кэширования, то вопрос о нагрузке вообще отпадает. Единственным минусом являются постоянные страницы, так что здесь есть над чем работать.
В следующей статье я рассмотрю вопросы оптимизации шаблонов WordPress.
Постоянная ссылка: http://maxsite.org/?p=150
Версия для печати
