В качестве драйвера для соединения с базой я использовал mysqli. Проблема началась, когда я добавил на свой тестовый сервер > 500 000 записей в одну таблицу. Соединение с базой стало занимать от 1 до 10 секунд, несмотря на то, что в настройках стояло:
что должно было означать, что подключение происходит через постоянное соединение.
mysql_pconnect делает все тоже самое, что и mysql_connect, за двумя важными исключениями:
Дело оказалось вот в чем. Файл /system/database/drivers/mysqli/mysqli_driver.php. Скрипт игнорирует «флажок» постоянного соединения и производит соединение через обычную функцию mysqli_connect:
У mysqli нет функции mysqli_pconnect. Постоянные соединения там организуются другим способом. Ответ с php.net:
Надо всего лишь добавить «p:» перед названием хоста. Переписываем функцию db_pconnect()
Это решение будет работать не ниже PHP 5.3.
Переписывать функции в ядре фреймворка не благодарное дело, но решение очень быстрое и простое. Если есть более изящное решение с возможностью расширить этот класс драйвера, то прошу в комментарии.
The mysqli Extension and Persistent Connections
$db['default']['pconnect'] = TRUE;
что должно было означать, что подключение происходит через постоянное соединение.
Немного теории
mysql_pconnect делает все тоже самое, что и mysql_connect, за двумя важными исключениями:
- При соединении функция пытается найти указатель на соединение к тому же хосту, с таким же логином и паролем. Если такое соединение найдено, то возвращается указатель на него, новое соединение не открывается.
- Соединение с сервером не будет закрыто по завершению работы скрипта. В этом случае mysql_close() не закрывает соединение, открытое через mysql_pconnect.
Решение
Дело оказалось вот в чем. Файл /system/database/drivers/mysqli/mysqli_driver.php. Скрипт игнорирует «флажок» постоянного соединения и производит соединение через обычную функцию mysqli_connect:
function db_pconnect(){
$this->db_connect();
}
У mysqli нет функции mysqli_pconnect. Постоянные соединения там организуются другим способом. Ответ с php.net:
To open a persistent connection you must prepend p: to the hostname when connecting.
Надо всего лишь добавить «p:» перед названием хоста. Переписываем функцию db_pconnect()
function db_pconnect(){
$this->hostname = 'p:'.$this->hostname;
$this->db_connect();
}
Замечание
Это решение будет работать не ниже PHP 5.3.
Переписывать функции в ядре фреймворка не благодарное дело, но решение очень быстрое и простое. Если есть более изящное решение с возможностью расширить этот класс драйвера, то прошу в комментарии.
Ссылки
The mysqli Extension and Persistent Connections