Из-за основанного на процессах дизайна PHP и использования запросов без сохранения состояния в расширении OCI8 отсутствует API пула соединений. Вместо этого следует использовать постоянные соединения с вызовом oci_pconnect()
. Это сохраняет соединения из одного HTTP-запроса для последующего использования, поэтому это намного быстрее.
(Внутренние для реализации OCI8, постоянные соединения действительно используют API пула сеансов интерфейса вызовов Oracle с фиксированным Размер пула только одного соединения. То есть каждое PHP соединение имеет свой собственный пул. Это полезно, поскольку пул сеансов - это технология, которая позволяет использовать DRCP (см. другие комментарии), а также документация Oracle по высокой доступности рекомендует использовать сеанс пулы, например, для событий FAN).
Не допускайте слишком большого числа PHP процессов, которые выполняются. Это сведет к минимуму количество необходимых подключений к БД и позволит больше использовать повторно. Это также уменьшит объем памяти, требуемый на каждом сервере БД для обработки соединений, поскольку они останутся открытыми. Только если серверам БД не хватит памяти, вы можете использовать пул DRCP .
Уменьшение перезапусков Apache, удаление тайм-аутов подключения сетевого брандмауэра и ограничение ресурсов БД таким образом холостые соединения не убиваются. Вы хотите, чтобы эти «постоянные соединения» были постоянными, чтобы они были немедленно доступны для использования, когда ваше приложение вызывает oci_pconnect()
. В противном случае OCI8 придется (внутренне) пересоздавать соединения без необходимости.
Далее вам нужно уменьшить количество «обходов» между PHP и базой данных для приложения, поскольку в медленной сети они действительно оказывают влияние. по производительности. Переместите как можно больше работы в БД, например, с помощью PL / SQL.
Если после каждого вызова oci_pconnect()
вы выполняете операторы типа ALTER SESSION
, переместите их в триггер LOGON. Или, по крайней мере, оберните их блоком PL / SQL:
begin
execute immediate
'alter session set nls_date_format = ''YYYY-MM-DD'' nls_language = AMERICAN';
-- other SQL statements could be put here
end;
Этот блок занимает одну поездку в оба конца, если выполняется из PHP. Если бы вы сделали то же самое в триггере LOGON, это потребовало бы нулевых циклов.
Для нормального выполнения операторов посмотрите, можете ли вы аналогичным образом поместить вызовы в один анонимный блок PL / SQL и использовать один oci_parse()
call.
Затем настройте запросы, извлекающие несколько строк, отрегулировав размер предварительной выборки . Опять же, это может помочь сократить количество обращений.
Если вы загружаете данные, рассмотрите возможность использования oci_bind_array_by_name()
или даже вызова Python (с помощью cx_ Oracle расширение) и с использованием executemany()
, поскольку они (опять же) сокращают круговые поездки.
Это базовые c подсказки. Вы можете найти другие в руководствах или The Underground PHP и Oracle Manual . Или вы можете рассмотреть альтернативную архитектуру, возможно, такую, которая объединяет запросы и выполняет их в «удаленной» базе данных, а затем отправляет все результаты обратно.
Не относится к производительности приложения, но поскольку у вас есть «удаленные» базы данных, вы можете использовать функции Oracle Net для обнаружения разорванных сетевых подключений и предотвращения «зависаний» при ожидании времени ожидания TCP. Посмотрите, как создать файл sq lnet .ora, в котором вы запускаете приложение PHP, и используйте такие параметры, как SQLNET.OUTBOUND_CONNECT_TIMEOUT
. Если вы не можете помешать брандмауэрам уничтожить неактивные подключения, вы можете использовать ENABLE=BROKEN
в строке подключения.