Небольшое
вступление
Началом
написания серии статей "Советы и трюки" послужил отчет "Tips and Tricks" Расмуса
Лирдофа (Rasmus Lerdorf) с конференции PHPCon2002, которая состоялясь 24 октября
2002 года в городе Milbrae, Калифорния, США. Изначально планировалось просто
перевести отчет по просьбам членов Клуба разработчиков PHP, но по мере чтения
статей возникло много спорных вопросов и разногласий с автором, поэтому я
постарался как можно более четко определить и разъяснить преимущества и
недостатки того, или иного подхода оптимизации решений.
Часть 1.
Оптимизация
1. Без
необходимости не используйте регулярные выражения.
В PHP кроме
регулярных выражений существует большое количество функций по обработке текста,
которые в некоторых случаях могут заменить их, экономя при этом ресурсы сервера.
Неправильно: <? $new = ereg_replace("-","_",$str);
?> Правильно: <? $new = str_replace("-","_",$str);
?> Неправильно: <? preg_match("/(\..*?)$/",$str,$reg);
?> Правильно: <? substr($str,strrpos($str,)); ?>
2.
Используйте ссылки при обработке больших массивов данных для экономии памяти
сервера.
Работа со
ссылками (references) является более приемлемой при обработке больших объемов
информации, хотя и немного медленней, чем работа с копией, но использует меньший
объем памяти. Поэтому Вы должны самостоятельно определить, запасы каких ресурсов
на сервере более рационально использовать - процессора или памяти.
3.
Постоянные (persistent) соединения с БД
Некоторые БД
более медленно выполняют создание новых соединений, чем другие БД. Чем дольше
происходит создание нового соединения, тем больший смысл имеет использовать
постоянное соединение с БД. Но учтите, что постоянные соединения связывают и
используют ресурсы сервера, даже тогда, когда эти соединения простаивают.
Учтите, в
PHP реализована функция отключения постоянных соединений, поэтому если у
провайдера в конфигурации PHP установлена директива mysql.allow_persistent =
Off, то соединения вызываемые функцией mysql_pconnect() будут обрабатываться как
mysql_connect().
Очень часто
встречаются советы не использовать постоянные соединения с БД. Это связано в
первую очередь с тем, что многопоточные веб-сервера, к которым относится и
Apache, не могут разделить со своими потомками соединение с БД. Таким образом
если следующий запрос приходит на другого потомка, то он создает новое
постоянное соединение, что со временем приводит к появлению большого количества
незакрытых соединений с БД и переполнению допустимого лимита max_connections в
MySQL. Возможно два решения этой проблемы: первое описано выше заключается в
запрете использования постоянных соединений, второе - использовать малое
значение времени жизни постоянного соединения в директиве wait_timeout
конфигурации MySQL. По умолчанию оно составляет 28800 сек. (8 часов), по
истечению которых после отсутствия активности соединения будет закрыто.
Помимо всего
этого существуют еще некоторые проблемы постоянных соединений с транзакциями и
блокировками таблиц. Так, если таблица блокируется запросом на транзакцию или
LOCK TABLE и при этом скрипт заканчивает свое выполнение до завершения
транзакции или выполнения разблокировки таблицы UNLOCK TABLE соответственно, то
вторичная попытка доступа к таблице через это же постоянное соединение будет
отклонена. При использовании непостоянного соединения с БД, при завершении
скрипта соединение закрывается автоматически и при этом снимает блокировку со
всех таблиц и завершает все транзакции. Решением этой проблемы есть регистрации
функции register_shutdown_function() которая бы по завершению скрипта снимала
блокировку с таблиц и завершала транзакции.
Так что
можете использовать, а можете и не использовать, все зависит от поставленных
задач.
4.
Используешь MySQL? Проверь mysql_unbuffered_query()
Небуферезированные
запросы к БД MySQL применяется так же как и mysql_query(). Разница заключается в
том, что вместо того, чтоб ожидать полного окончания запроса сохранить результат
в клиентском API, небуферизированный запрос делает доступными результаты своего
выполнения как можно скорее, минуя буферизацию в клиентском API. Таким образом
Вы получаете боле быстрый доступ к данным с меньшими затратами памяти.
Недостатком использования такого типа запросов является невозможность получить
доступ к функции mysql_num_rows(),этои запросы медленнее на маленьких выборках
SELECT, а также хотелось бы заметить то, что при выполнении любого другого
запроса, все данные которые небыли выведены, будут потеряны.
5. В
поисках идеала
Если решения
выглядят для Вас комплексно, то наверняка найдется более простой и очевидный
подход к решению задачи.
|