mysqli_store_result () vs. mysqli_use_result ()

Вопрос

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

История

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

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

 /* 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() я обнаружил, что в образце кода mysqli::use_result() -page: $result->free(); было еще одно исключение $result->free(); стал $result->close(); , Однако мои надежды на выяснение правды вскоре были разрушены, когда я обнаружил, что на той же странице во втором примере кода (процедурный эквивалент) mysqli_free_result($result); , а не ожидаемый mysqli_close_result($result); ,

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

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

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

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

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

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

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

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

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

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