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