Мне интересно, почему иногда результаты запроса возвращаются довольно быстро, а иногда кажется, что между вызовами 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
, или что это значит точно?