Чтение 65k строки подвешивает PHP/MySQL

Я разрабатываю приложение PHP, которое обрабатывает адреса IP. Я работаю с mysql таблицами, содержащими до 4 миллиардов строк.

У меня есть сценарий, который в настоящее время должен выбирать 65 536 адресов от этой таблицы, и mysql <-> php интерфейс не удается дать ответ через PHP или даже через phpMyAdmin, когда я пытаюсь извлечь эти 65K строки. Если используется в командной строке, mysql даст 65K строки без проблемы приблизительно через 0,2 секунды.

Таблица, содержащая IP-адреса, имеет 3 индекса (1 уникальное, 2 основных), которые, как предполагается, помогают ей пойти быстрее, но я просто не могу закончить наличие mysql, отдают ассоциативный массив к PHP для продолжения моей обработки данных.

Сервер является выделенной недавней машиной Xeon приблизительно с 32 ГБ памяти (я не знаю точные спецификации).

Какие-либо подсказки о том, что могло продолжаться здесь?

Заранее спасибо.

2
задан 25 June 2015 в 21:10
1 ответ

mysqli и PDO по умолчанию работают в буферном режиме . Это означает, что на ваши запросы фактически действует лимит памяти PHP-процесса.

С http://php.net/manual/en/mysqlinfo.concepts.buffering.php:

.

[В буферизованном режиме] результаты запросов немедленно передаются с сервера MySQL на PHP. и затем хранятся в памяти PHP-процесса. Это позволяет дополнительные операции, такие как подсчет количества строк и перемещение (ищет) текущий указатель на результат. Это также позволяет выдать дальнейший запросы по одному и тому же соединению при работе с результирующим набором. Обратной стороной буферизованного режима является то, что большие наборы результатов могут потребовать достаточно много памяти.

Вы должны либо увеличить лимит памяти PHP-процессов в вашем php.ini, увеличив значение параметра memory_limit, либо сказать запросам использовать unbuffered mode:

Unbuffered MySQL-запросы исполняют запрос и затем возвращают ресурс пока данные еще ждут на сервере MySQL. Это использует меньше памяти на стороне PHP, но может увеличить нагрузку на server.

Mysqli пример:

$mysqli  = new mysqli("localhost", "my_user", "my_password", "world");
$uresult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);

PDO пример:

$pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass');
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
1
ответ дан 3 December 2019 в 12:46

Теги

Похожие вопросы