Pull to refresh

Альтернатива mysql_pconnect для драйвера mysqli в php 5.3

CodeIgniter *
В качестве драйвера для соединения с базой я использовал mysqli. Проблема началась, когда я добавил на свой тестовый сервер > 500 000 записей в одну таблицу. Соединение с базой стало занимать от 1 до 10 секунд, несмотря на то, что в настройках стояло:
$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
Tags:
Hubs:
Total votes 29: ↑22 and ↓7 +15
Views 7.7K
Comments Comments 26