Понимание sqlite3_step и почему оно «занимает время» между итерациями - PullRequest
0 голосов
/ 25 сентября 2019

Мне интересно, почему иногда результаты запроса возвращаются довольно быстро, а иногда кажется, что между вызовами sqlite3_step() проходит некоторое время.Например:

rc = sqlite3_prepare_v2(db, "SELECT * FROM mytable m GROUP BY field1, field2, field3, field4, field5 LIMIT 500", -1, &stmt, NULL);
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW);

Каждый sqlite3_step занимает примерно одно и то же время, когда я просматриваю операторы печати, и операторы выборки складываются, чтобы занять около 6.5s

И затем снормальный, быстрый неагрегированный запрос, sqlite3_step почти мгновенный:

rc = sqlite3_prepare(db, "SELECT * FROM mytable LIMIT 500", -1, &stmt, NULL);

В приведенном выше запросе все занимает менее 0.1s для запроса и получения.

Я понимаю, почему сам запросбудет намного медленнее, но кажется, что sqlite3_stmt на самом деле «ничего не делает», и вся работа по SQL идет в sqlite3_step и распределяется внутри каждого шага.Несколько вопросов из этого:

  • Почему набор результатов не выбирается один раз, а последовательные шаги возвращаются мгновенно (для небольшого набора запросов, такого как описанный выше, где количество записей меньше 1 КБ)?
  • Что именно sqlite3_prepare делает?Касается ли он данных фактического файла (или в памяти), или это просто «настройка» для выполнения запроса?
  • Что SQLite делает между каждым sqlite3_step, что занимает дополнительное время междушаги (если запрос уже был «выполнен»)?

Документация по этому методу приведена в списке здесь , но она мало говорит о том, что на самом деле делает другойчем сказать, какие коды возврата это может дать.Из документов:

Эта подпрограмма используется для оценки подготовленного оператора, который был ранее создан интерфейсом sqlite3_prepare ().Оператор оценивается до точки, в которой доступен первый ряд результатов.Чтобы перейти ко второму ряду результатов, снова вызовите sqlite3_step ().Продолжайте вызывать sqlite3_step (), пока инструкция не будет завершена.Операторы, которые не возвращают результаты (например, операторы INSERT, UPDATE или DELETE), выполняются до завершения при одном вызове sqlite3_step ().

Что означает «до завершения» в этом случае?В основном это просто LIMIT 1, и пользователь должен снова вызвать его, чтобы сделать OFFSET 1, или что это значит точно?

1 Ответ

2 голосов
/ 25 сентября 2019

sqlite3_prepare() компилирует оператор в внутренний байт-код sqlite .sqlite3_step() оценивает этот байт-код до точки, в которой возвращается строка или нет больше строк.Следующий вызов возобновляет оценку в этой точке;он не всегда вычисляет все строки результатов одновременно, но часто только по одной за раз.sqlite3_step() может занять разное время в зависимости от того, сколько нужно сделать, чтобы получить следующую строку (например, группы обработки разных размеров), если страницы должны быть извлечены с диска вместо того, чтобы присутствовать в кэше страниц и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...