Ниже описаны два параметра соединения с сервером БД MySQL с помощью модуля DBD::mysql, которые могут использоваться для повышения производительности.
- mysql_server_prepare - операторы сохраняются на стороне сервера.
- mysql_use_result - результат запроса не сохраняется на клиенте перед использованием (умолчательное поведение называется mysql_store_result). Может быть применено:
- на уровне database handler: добавлением mysql_use_result=1 к DSN или оператором
$dbh->{mysql_use_result}=1;
- или на уровне statement handler - в операторе:
$dbh->prepare('select * from bigtable', {mysql_use_result => 1});
или (после prepare и до execute) оператором:$sth->{mysql_use_result} = 1;
Пользу от такого поведения можно почуствовать, если оператор возвращает очень много записей - порядка нескольких миллионов. При умолчательном mysql_store_result perl (по крайней мере, v 5.8.8 на FreeBSD 7.0) пожирает всю доступную память - и умирает, а при mysql_use_result - ничего, живет - и даже обходится не очень большим количеством памяти. К недостаткам этого метода работы с результатом man-страница DBD::mysql (3) относит
tends to block other processes,
но не очень понятно, что имеется в виду - по крайней мере, у автора по ходу длинного запроса другие процессы продолжали успешно читать из базы и писать в нее. Возможно, эффект бы наблюдался при запросе на запись - но в моей практике запросы на запись с таким размером возвращаемого результата не встречались.
- на уровне database handler: добавлением mysql_use_result=1 к DSN или оператором
Активируется с помощью добавления выражения mysql_server_prepare=1 к DSN, напр.:
$dbh = DBI->connect('DBI:mysql:db1:localhost;mysql_server_prepare=1', 'user', 'pass');
По идее такой подход должен повышать производительность массовых запросов. Проверяем на заведомо слабой машине (сервер и клиент на одном и том же компьютере). Миллион insert выполняется быстрее на 11%, миллион update - на 19%, миллион delete - на 11%. Стоило оно того? Не знаю. Но вроде противопоказаний не обнаружено.