Подтвердить что ты не робот

Mysqli_store_result() vs. mysqli_use_result()

Вопрос

В чем разница между mysqli::store_result() и mysqli::use_result()?

История

Нечеткая документация

Документация на PHP.net кажется очень расплывчатой ​​о различии между ними. mysqli::use_result() -page не предлагает никаких кодовых образцов и связывает вас с mysqli::multi_query() -page, чтобы искать их. На этой странице приведен следующий пример кода (см. Страницу для полного кода):

/* store first result set */
if ($result = $mysqli->store_result()) {
    while ($row = $result->fetch_row()) {
        printf("%s\n", $row[0]);
    }
    $result->free();
}
/* print divider */
if ($mysqli->more_results()) {
    printf("-----------------\n");
}

mysqli::store_result() -page использует точно такой же код-образец, за одним исключением:

/* store first result set */
if ($result = $mysqli->use_result()) {

Да... store_result стал use_result. Обратите внимание, что даже комментарий выше все еще говорит "хранить".

Еще более запутанный

Посмотрев образцы кода, подумал я; "Все в порядке, так что это псевдоним". Но ждать! Документация дает следующие описания:

  • mysqli_store_result - переносит результирующий набор из последнего запроса
  • mysqli_use_result - инициировать поиск набора результатов

Они кажутся двумя разными вещами и вообще не похожи на псевдонимы. Присмотревшись, я обнаружил, что в образце кода mysqli::use_result() -page было еще одно исключение: $result->free(); стал $result->close();. Однако мои надежды на то, чтобы узнать правду, вскоре были разрушены, когда я обнаружил, что на той же странице во втором примере кода (процедурный эквивалент) использовался mysqli_free_result($result);, а не ожидаемый mysqli_close_result($result);.

4b9b3361

Ответ 1

mysqli::store_result() будет извлекать весь набор результатов с сервера MySQL, а mysqli::use_result() будет извлекать строки один за другим.

Это также упоминается в документах mysqli::use_result, с которыми вы ссылались:

Функция mysqli_use_result() не переносит весь набор результатов из базы данных и, следовательно, не может использоваться такие функции, как mysqli_data_seek(), чтобы перейти к определенной строке внутри набора. Чтобы использовать эту функциональность, набор результатов должен быть сохранен с помощью mysqli_store_result(). Не следует использовать mysqli_use_result(), если выполняется большая обработка на стороне клиента, так как это свяжет сервер и предотвратит обновление других потоков от любых таблиц, из которых извлекаются данные.

Обычно вы всегда можете использовать mysqli::store_result(), если у вас нет достаточной причины не сразу читать все строки с сервера.

Ответ 2

use_result возвращает небуферизованный результат.

store_result возвращает буферный результат.

Ответ 3

Я думаю, что эта разработка может помочь людям получить здесь от langauges, которые поддерживают извлечение либо через массивы, либо в счетчики. Потому что это просто разница. Для .NET это будет та же разница, что и GetDirectories (store_results) vs EnumerateDirectories (use_results) (и парсинг File/DbResult/CSV/XMl Parsing).

Вариант перечислителя использует меньшую (PHP) клиентскую память и может извлекать следующую строку asynchronoulsy в фоновом режиме, в то время как текущая строка обрабатывает, что делает ее как большую память, так и время обработки эффективным на стороне клиента. За счет использования ресурсов сервера (SQL) дольше (поскольку набор результатов не был полностью передан).

В свою очередь, метод get/array будет извлекать данные в одной операции блокировки, занимая больше памяти на стороне клиента для освобождения памяти БД ранее.

Лично я использовал бы по умолчанию для пути, отличного от Enumerator, если у вас не возникли проблемы с памятью. В .NET вы должны использовать способ Enumerator, если вы используете лимит 2/3 GiB для процессов x32. Здесь важны особые EnumerateLines для файлов. С результатами DB это не должно начаться. Результат 2 гигабайта DB является либо способом недостаточно фильтрованным (делать больше фильтрации в Query), либо содержит много Blob (которые вы должны загружать по частям или даже позволить браузеру удалять через обработчик http, если это возможно).