Запись большого объёма данных, почему переподключение к базе данных дает прирост производительности?

от автора

Доброго времени суток, жители Хабра.

Работая над парсером поисковых запросов (около семи миллионов по базе Пастухова) для одного интернет магазина встал вопрос записать результаты обработки. Выходило очень много готового продукта встал вопрос как записать быстро результаты. Поискав решения в сети нашёл, что mysqli_multi_query работает быстрее других форм обращений к базе данных (говорится о 10 000 запросов в секунду). Его и стал использовать.

Для теста стал наращивать объёмы пакетов данных, что бы посмотреть на производительность, но тут возникла странная ошибка: после 5000-7000 insert’ов база отказывалась дальше писать данные.

//в рамках одного подключения к базе данных $conn = mysqli_connect("192.168.0.72", "root", "root", "t_parsed_words"); ... foreach($itog as $k=>$v) $query[] = "INSERT IGNORE INTO `tag_name_count` (`tag`,`word`,`count`) VALUES ('$tag','$k',$v);"; ... $slice_query = implode('',array_slice($query, $i*5000, 5000)); ... mysqli_multi_query($conn, $slice_query); ... mysql_close($conn);

Разбивка на блоки по 5000 тоже не дала результатов. Уже на следующей итерации цикла всё стопорилось. Надо ещё отметить, что стартовал проект без меня и я лишь к нему присоединился, решать задачи такого уровня на PHP своего рода извращение. Всё тоже можно было реализовать в рамках того же С#.
Но надо было довести проект до логического конца. Использование placeholder’a затуманило взор… даже mysqli_multi_query ни кто не использовал в коллективе по этой причине. Решение оказалось на удивление простым и в то же время не до конца мне понятным:

... $count_slice = (int)(count($query)/5000) + 1; //новая пачка = новое подключение for($i=0;$i<$count_slice;$i++){ //реконект доводит транзакции до конца, дефолтит резервируемые ресурсы? $conn = mysqli_connect("192.168.0.72", "root", "root", "t_parsed_words"); $slice_query = implode('',array_slice($query, $i*5000, 5000)); if (mysqli_connect_errno()) { printf("<font color=red>Не удалось подключиться: %s</font><br>", mysqli_connect_error()); exit(); } if(mysqli_multi_query($conn, $slice_query)) echo 'Результаты успешно записаны, '.($i+1).' из '.$count_slice.'<br>'; else echo '<font color=red>Ошибка записи '.($i+1).' из '.$count_slice.'</font><br>'; mysql_close($conn); } unset($query);

Стопорения стразу прекратились. 200 000 запросов в секунду, машина в локальной сети рядом… Измерение скорости не привожу они очень специфичны, использовался скоростной жесткий диск Corsair CSSD-F128GBGS-BK. В целом компьютер обычный.

Может тут замешана асинхронность? Хотелось бы узнать причину этого явления у знатоков…

Использовал:
Multiquery и скорость выполнения:
forum.php.su/topic.php?forum=28&topic=4026&postid=1318871174#1318871174 (17 Октября, 2011)

ссылка на оригинал статьи http://habrahabr.ru/post/185964/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *