Советы по оптимизации php & mysql

08 03 2007


Советы по оптимизации php & mysql

Тот кто хочет получить высокую проиводительность – не пишет просто быстрые скрипты. Для достижения высокой производительности PHP требуется хорошее понимание работы основных аппаратных средств, операционной системы и другого ПО, типа сервера и базы данных

Оптимизация баз данных

Если запрос занимает много времени воспользуйтесь командой EXPLAIN чтобы узнать каким образом Mysql выполняет этот запрос

Explain Select …

Оптимизация таблиц

Optimize table table_name [,table_name]

Выбирайте самый эффективные типы данных:
- mediumint часто оказывается эффективнее int
- обьявляйте колонки как Not null
- избегайте колонок blob, text и varchar
- первичный ключ таблицы должен быть как можно более коротким
- увеличивайте эффективность индекса – если известно что первые Х символом колонки уникальны то генерируйте индекс по этому числу символов
- не делайте индексы для каждой колонки таблицы

Правильно спроектирование базы данных должны иметь индексы, лучшие индексы те – которые создаются в команде Create table и учавстсвуют в множестве запросов. Лишние индексы замедляют запросы на обновление и удаление.
MySQL использует индексы автоматически, чтобы узнать какие индексы используются в текущем запросе нужно использовать команду Explain

Оптимизация запросов SELECT
Для их оптимизации проверьте можно ли добавить индекс. С помощью explain проверьте какие индексы используются и не следует ли их создать.

Оптимизация запросов INSERT
Этого можно добится используя команду INSERT DELAYED вместо INSERT, Клиент получает потверждение о успеной вставке хотя операция на сервере еще не завершена.
При загрузке данных из файла используйте LOAD DATE INFILE что в 20 раз быстрее чем множественные INSERT
Блокировка таблиц перед вставкой ускоряет эту операцию
LOCK TABLES a WRITE ;
INSERT…
INSERT…
UNLOCK TABLES;

Оптимизация запросов UPDATE
Оптимизируйте команды UPDATE как если бы они были SELECT

Оптимизация запросов DELETE
Для того чтобы удалить все записи из таблицы используйте команду TRUNCATE TABLE table_name вместо DELETE

Оптимизация соединений
Можно устанавливать постоянные соединения и избежать создания нового соединения с базой данных для каждого запроса :
mysql_pconnect


Дополнительные советы по оптимизации :
- Избегайте сложных вопросов к таблицам которые много обновлялись
- В таблицах которые часто обновляются следует избегать колонок BLOB и VARCHAR
- Ошибочно делить таблицу на несколько только изза того что она кажется большой.
- Ведите хешированную колонку
Если колонка короткая и данные в ней уникальны это может оказатся быстрее чем индекс по нескольким колонкам
- Используйте значения по умолчанию – вставляйте данные явным образом только когда они не соответствуют со значением по умолчанию
- Используйте колонки auto_increment для создания уникальных значений и ключей


Кэширование
Кэширование – это сохранение данных для будущего повторного использования. Позволяет снизить нагрузку на сервер а также быть сравнительно независимым от источника данных (если база падает то систему продолжает работать на кэше)

Кэшировать можно в базу даных, в файлы, в файл DBM, в совместно используюмую память, в память.
Файл DBM хороший вариант когда работа с БД нежелательна или невозможно создавать по файлу для каждой записи в кэш (пример реализации : www.sleepycat.com)


Управление процессами
В некоторых операционных системах, например, в Windows, создание нового процесса – это медленная операция. Это означает, что CGI процесс, вызываемый для каждой операции, будет работать значительно медленнее. Запуск PHP в multi-threaded (в виде модуля) режиме должно увеличить скорость ответа (примечание: старые версии PHP неустойчивы в данном режиме).

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

Также выберите хорошие испытательные данные. Если ваша база данных, как ожидается, будет хранить только 100 000 записей, избегайте тестирования ее только со 100 записями, вы будете потом об этом сожалеть.

APACHE

Apache сконфигурирован при помощи файла httpd.conf. Следующие параметры особенно важны при настройке дочерних процессов:

Параметр Поумолчанию Описание
MaxClients 256 Максимальное число дочерних процессов, которые может создать сервер. Значение поумолчанию 256 означает, что одновременно может быть обработано 256 HTTP запросов. Любые дальнейшие запросы будут поставлены в очередь.

StartServers 5 Количество дочерних процессов, которые будут созданы сразу после старта сервера.

MinSpareServers 5 Число неактивных дочерних процессов, которые должны быть созданы. Если число неактивных процессов падает ниже этого числа, то 1 ребенок создается первоначально, 2 на следующую секунду, 4 еще через секунду, и так далее, пока не будет создано 32 дочерних процесса с интервалом в секунду.

MaxSpareServers 10 Если создано больше, чем данное число дочерних процессов, то эти дополнительные процессы будут остановлены.

MaxRequestsPerChild 0 Устанавливает какое число HTTP запросов ребенок должен обработать перед завершением. Если вы устанавливаете ее в 0, то дочерний процесс никогда не умирает. Установите его в пределах от 100 до 10000, если вы подозреваете утечки памяти или неправильно использование ресурсов.


Для больших сайтов наилучшими значениями будут близкие кэтим:
MinSpareServers 32
MaxSpareServers 64
Apache под Windows ведет себя иначе. Вместо того, чтобы использовать дочерние процессы, Apache использует треды. Вышеупомянутые параметры не используются. Вместо этого мы имеем один параметр: ThreadsPerChild который имеет значение поумолчанию – 50. эта переменная указывает число тредов, которые могут быть порождены Apache. Поскольку в Winodws есть только один дочерний процесс, то количество HTTP запросов, которые он может обработать, равняется 50. Для серверов сети, которые испытывают более серьезные нагрузки, увеличьте этот параметр от 256 до 1024.

Другие полезные параметры, которые вы можете изменить приведены ниже:

Параметр Поумолчанию Описание
SendBufferSize Определяется операционной системой. Определяет объем буфера вывода (в байтах), используемого в TCP/IP соединениях. Этот параметр прежде всего полезен для переполненных или медленных сетей, когда пакеты необходимо буферизировать. В этом случае, установите этот параметр близким к размеру самого большого пересылаемого файла. Один TCP/IP буфер будет создан при соединении.

KeepAlive [on|off] On В оригинале HTTP спецификации, каждый HTTP запрос должен создавать новое соединение с сервером. Keep-alive заголовок был создан, чтобы уменьшить нагрузку на сервер. Параметр keep-alive говорит серверу, чтобы он использовал тоже самое соединение через socket (сокет) для нескольких HTTP запросов.

Если у вас есть отдельные сервер, который обслуживает все изображения (images), то вы можете выключить этот параметр. Подобная техника поможет значительно сэкономить ресурсы сервера.

KeepAliveTimeout 15 Количество секунд для удержания сокет-соединения. Это времявключает в себя генерацию контента и ответ клиента. Если клиент не реагирует в течение этого времени – будет создано новое соединение.

Это значение не должно быть большим, иначе сокет будет простаивать в этот период.

MaxKeepAliveRequests 100 Сокет-соединения будут закончены, как только их количество достигнет этой цифры. Установите большое значение, но меньше MaxClients или ThreadsPerChild.

TimeOut 300 Отсоединиться, если время простоя превышает это число. Вы можете установить меньшее значение, если ваши клиенты имеют небольшую задержку.

LimitRequestBody 0 Максимальный размер PUT или POST. 0 – нет лимита.

Если вы не требуете DNS поиска и не используете htaccess для настройки отдельных директорий в Apache, вы можете задать:

# выключить DNS поиск: PHP скрипты получают только IP адрес

HostnameLookups off

# отключить проверку htaccess



AllowOverride none



Если вас не волнует безопасность папок при вызове симлинков, включите FollowSymLinks и выключите SymLinksIfOwnerMatch, чтобы предотвратить дополнительный системный вызов lstat():

Options FollowSymLinks

#Options SymLinksIfOwnerMatch


PHP скрипт загружается в Zend Engine и компилируется в opcode. Opcode может быть оптимизирован с использованием необязательного оптимизатора, названного Zend Optimizer. В зависимости от скрипта, он может увеличить скорость выполнения PHP скрипта до 50%.

Один из секретов высокой производительности состоит не в том, чтобы написать быстрый PHP код, а в том, чтобы кэшировать результаты выполнения скрипта в файл или общую память. Скрипт запускается однажды, генерируемый HTML захватывается и все последующие обращения к скриптуприводят к показу уже готового HTML.

И, наконец, HTML, отдаваемый браузеру клиента, может быть сжат. Это включается добавлением следующего кода вначале вашего скрипта:

ob_start("ob_gzhandler");

HTML кэширование с использованием PEAR Cache
PEAR Cache – это набор классов для кэширования разнообразных типов данных, включая HTML и картинки.

С тех пор, как я написал эти строки, была создана более продвинутая система кэширования PEAR: Cache Lite (http://pear.php.net/package/Cache_Lite);
Cache конструктор принимает первым параметром тип драйвера для сохранения кэша. Доступны следующие драйверы: файл, база данных, общая память (смотрите папку: pear/Cache/Container).

Другой способ использования PEAR Cache – это сохранение значения переменных или других данных. Для реализации этого – используйте основной Cache класс

Для сохранения используемых данных применяйте функцию save(). Если выбранный вами уникальный ключ уже существует, вы можете использовать функцию generateID(). Объекты и массивы могут быть сохранены благодаря использованию функции serialize() внутри функции save().

Использование тестов производительности
Если вы хотите получить наиболее реалистичные тесты производительности вебсервера, вам необходим инструмент, умеющий посылать разнообразные HTTP запросы. На Unix обычные инструментальные средства тестирования включают ab (сокращение от apachebench), который являются частью пакета Apache. И более нового flood (http://httpd.apache.org/test/flood). На Windows NT/2000 вы можете использовать Microsoft's free Web Application Stress Tool (http://webtool.rte.microsoft.com).
Эти утилиты могут делать параллельные множественные HTTP запросы моделируя тем самым множество клиентов сети, и выдавать вамдетальную статистику по завершению теста.

На Windows 2000 вы можете использовать Performance Monitor или Task Manager для просмотра статистики своей системы.

Альтернативно, вы можете использовать специальные инструменты для профелирования: APD (http://www.linuxjournal.com/article.php?sid=7213) или Xdebug (http://xdebug.derickrethans.nl/). Еще вы можете прочитать специальную статью на эту тему: http://phplens.com/phpeverywhere/node/view/52.

Дополнительный способ ускорить вышеприведенный код – это использование буферизации вывода. Это позволит накапливать информацию внутренне и потом вывести ее целиком на экран в конце выполнения скрипта. Это существенно уменьшит нагрузку на сеть за счет использования большего количества памяти и увеличения времени ожидания. В части моего кода, состоящего полностью из команд echo, улучшение работы достигло 15%.

ob_start();
for ($j=0, $max = sizeof($arr), $s = '';$j < $max;$j++)
echo $arr[$j] . '
';

Резюме
Чем больше вы разбираетесь в программном обеспечении, которое вы используете (Apache, PHP, IIS, база данных), и чем глубже ваши знания операционной системы, организации сети, аппаратного обеспечения сервера, тем лучше вы сможете выполнить глобальную оптимизацию вашего кода и вашей системы.
Для PHP скриптов самое узкое место обычно – это центральный процессор. Два процессора, вероятно, будут лучше, чем два гигабайта оперативной памяти.
Сборка PHP с параметром configure –enable-inline-optimization позволяет сделать максимально быстрый исполняемый файл.
Оптимизируйте вашу базу данных и индексы, которые чаще всего используются в параметре WHERE ваших SQL запросов. ADODB – очень популярная библиотека абстрактного доступа – позволяет работать в режими оптимизации SQLзапросов, где вы можете всесторонне изучить ваши неудачные SQL запросы, а также определить, в каком скрипте они выполняются.
Используйте кэширование HTML, если ваши данные редко меняются. Даже если ваши данные меняются каждую минуту – кэширование может помочь, если данные синхронизировать с кэшем. В зависимости от сложности кода, кэширование позволяет улучшить скорость до 10 раз.
Тестируйте производительность вашего сложного кода на ранних этапах (или по крайней мере его опытные образцы), таким образом вы получите чувство ожидаемых параметров работы, прежде чем будет слишком поздно. Попробуйте использовать реалистические количества испытательных данных, чтобы гарантировать должную масштабируемость.
Рассмотрите возможности использования кэширования опкода. Это дает прирост производительности на 10-200% в зависимости от сложности вашего кода. Обязательно сделайте стресс тестирование вашего кода, прежде чем устанавливать оптимизаторы на реально работающий сервер, поскольку некоторые из них более надежны чем другие.
Используйте ob_start() в начале вашего кода. Это даст вам повышение производительности на 5-15%. Вы также можете использовать gzip сжатие для организации быстрых загрузок (это требует дополнительных ресурсов центрального процессора).
Рассмотрите возможность установки Zend Optimizer'а. Это бесплатное программное обеспечение делает некоторую оптимизацию, но будте внимательны – некоторые скрипты фактически замедляются, когда установлен Zend Optimizer. В основном, Zend Optimizer очень полезен, когда ваш код содержит множество циклов.
Оптимизируйте код циклов. Переместите определения, по которымработает цикл перед циклом.
Используйте массивы и строковые функции везде, где это возможно. Они работают значительно быстрее, чем написание аналогичного кода.
Самый быстрый способ связать многократные небольшие строки в одну – это использовать буфер вывода (ob_start()) и печатать echo в буфер. В конце получить данные функцией ob_get_contents. Это работает, потомучто для буферизации выделяется первоначальный буфер в 40 кб, который растет кусками по 10 кб.
Работая с массивами и объектами используйте ссылки где это возможно. Если это короткий скрипт, и обслуживание кода – это не проблема, вы можете использовать глобальные переменные для сохранения объектов и массивов.
Если у вас много скриптов, использующих переменные сессии, рассмотрите возможность скомпилировать PHP для использования общедоступной памяти для сессий, или используйте RAM диск для их хранения. Включите эти возможности configure –with-mm, затем перекомпилируйте PHP, а также установите session.save handler = mm в php.ini.
Для поиска подстроки, используйте самую быструю команду strpos(), preg_match() и уж затем ereg(). Точно также str_replace() быстрее чем preg_replace(), которая, в свою очередь, быстрее, чем ereg_replace().
Располагайте наиболее часто встречающиеся утверждения switch в самом верху. Если большинство случаев попадает под значение по умолчанию, определите его также в самом начале.
Обработка XML данных регулярными выражениями работает значительно быстрее, чем использование SAX и DOM.
Делайте unset() неиспользуемых более переменных, чтобы освободить память. Это главным образом полезно для ресурсов и больших массивов.
Для классов с глубокой иерархией расширенные функции работаютбыстрее, чем определенные в основном классе (родительском). Рассмотрите возможность копирования часто используемых функций из основного класса в наследующий.
Рассмотрите возможность написание вашего кода как расширение PHP или Java класс или COM объект, если вы нуждаетесь в сверхскорости. Будте осторожны при обмене данными между COM и Java.
Бесполезная оптимизация
Некоторые виды оптимизации полезны. Другие – напрасная трата времени. Часто полезность усовершенствования пренебрежимо мала. Часто, внутренние изменения в PHP делают щипковые изменения кода устаревшими.

Применение более быстрых функций:
- strstr() вместо ereg()
- str_replace вместо ereg_replace

Если регулярные выражения нужны то стоит предпочесть PCRE (Perl Compatible Regular Expressions)

Есть три функции для ввода содержимого:
readfile() ;include() ;require()

readfile лучше для чтения фрагментов где нет кода пхп.
Defined tags for this entry: 1
Pages: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | All


Обратные ссылки


Нет обратных ссылок

Комментарии

Показывать комментарии (Как список | Древовидной структурой)
Нет комментариев.

Добавить комментарий


Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA