Как преждевременно закончить mysql_use_result() / mysql_fetch_row()?
Я нахожусь в процессе написания моего первого клиента C для MySQL 5.5 и наткнулся на следующую страницу в документации. Почти в конце написано (жирный шрифт мой, курсив не мой):
Преимущество mysql_use_result() - [...]. Недостатки в том, что [...]. Кроме того, вы должны извлечь все строки, даже если в процессе поиска вы определили, что нашли информацию, которую искали.
Последнее предложение мне не понятно.
1) Что произойдет, если я не пойду по этой линии?
2) Я думаю, что на самом деле должен быть способ преждевременного прекращения выборки строк, если я решу, что у меня достаточно информации (в противном случае все это не имело бы большого смысла в моих глазах).
Я понимаю, что может произойти что-то плохое, если я просто перестану извлекать строки, а затем попытаюсь выполнить следующий оператор, но разве нет такой функции, как mysql_finish_fetch() или что-то в этом роде?
И что будет, если я позвоню mysql_free_result()
? Это должно освободить результат, даже если я еще не извлек все строки, поэтому было бы безопасно вызывать его в середине извлечения и продолжить то, что я хотел бы сделать. Я здесь не прав?
1 ответ
Это звучит как внутренняя проблема с потоками, которую MySQL предоставляет клиенту. Поговорите об этом с различными проблемами MySQL. Суть в том, что MySQL, по-видимому, имеет конечное число "искателей" внутри и использует mysql_use_result()
очевидно, посвящает один из них вашему запросу API. Кроме того, MySQL, по-видимому, не имеет открытого вызова API для отмены такого запроса. Единственный вариант - довести выборку до конца.
Немного более длинная версия: внутри курсоры MySQL, по-видимому, имеют единый путь кода - я думаю, для производительности в общих случаях. Этот путь кода завершается только тогда, когда курсор не находит больше результатов. Когда вы используете более распространенный mysql_store_result()
MySQL сделал это уже перед возвратом результата в приложение. Когда вы используете mysql_use_result()
Однако MySQL требует, чтобы вы выполняли "грязную работу" итерации остальной части набора результатов, чтобы очистить курсор. Веселье.
Из документации:
mysql_use_result()
инициирует получение набора результатов, но фактически не считывает набор результатов в клиент, какmysql_store_result()
делает. Вместо этого каждая строка должна быть извлечена индивидуально путем вызоваmysql_fetch_row()
, Это читает результат запроса непосредственно с сервера, не сохраняя его во временной таблице или локальном буфере, что несколько быстрее и использует намного меньше памяти, чемmysql_store_result()
, Клиент выделяет память только для текущей строки и буфера связи, который может увеличиться доmax_allowed_packet
байт.С другой стороны, вы не должны использовать
mysql_use_result()
для блокировки чтения, если вы выполняете много обработки для каждой строки на стороне клиента, или если вывод отправляется на экран, на котором пользователь может ввести^S
(остановить прокрутку). Это связывает сервер и препятствует тому, чтобы другие потоки обновляли любые таблицы, из которых извлекаются данные.Когда используешь
mysql_use_result()
, вы должны выполнитьmysql_fetch_row()
пока не будет возвращено значение NULL, в противном случае невыполненные строки возвращаются как часть набора результатов для вашего следующего запроса. C API выдает ошибкуCommands out of sync; you can't run this command now
если вы забудете это сделать!
Итак, чтобы на самом деле ответить на ваши вопросы:
1) Что произойдет, если я не пойду по этой линии?
C API вернет сообщение об ошибке: Commands out of sync; you can't run this command now
2) Я думаю, что на самом деле должен быть способ преждевременного прекращения выборки строк, если я решу, что у меня достаточно информации (в противном случае все это не имело бы большого смысла в моих глазах).
Казалось бы, но нет. Вы должны полностью повторить набор результатов.