Sqlite LIMIT / OFFSET запрос


153

У меня простой вопрос с Sqlite. Какая разница между этим:

Select * from Animals LIMIT 100 OFFSET 50

и

Select * from Animals LIMIT 100,50

9
Пожалуйста, отметьте его как ответ, если он очистил ваши сомнения, как вы упомянули в комментариях.
Мубашар

Ответы:


270

Две синтаксические формы немного сбивают с толку, потому что они переворачивают числа:

LIMIT <skip>, <count>

Эквивалентно:

LIMIT <count> OFFSET <skip>

Это совместимо с синтаксисом из MySQL и PostgreSQL. MySQL поддерживает обе формы синтаксиса, и его документы утверждают, что второй синтаксис с OFFSET должен был обеспечить совместимость с PostgreSQL. Документы PostgreSQL показывают, что он поддерживает только второй синтаксис, а документы SQLite показывают, что он поддерживает оба, рекомендуя второй синтаксис, чтобы избежать путаницы.

Кстати, использование LIMIT без предварительного использования ORDER BY может не всегда дать вам ожидаемые результаты. На практике SQLite будет возвращать строки в некотором порядке, вероятно, в зависимости от того, как они физически хранятся в файле. Но это не обязательно означает, что это в том порядке, как вы хотите. Единственный способ получить предсказуемый порядок - явно использовать ORDER BY.


2
LIMIT <count> OFFSET <skip>более понятно. Спасибо.
Гвидо Мокко

Этот аналогичный ответ имеет хорошее решение с хорошей производительностью, если порядок строк имеет значение. stackoverflow.com/a/28860492/5016333
Родриго V

23

Последний является альтернативным синтаксисом с одной оговоркой :

Если вместо ключевого слова OFFSET используется запятая, то смещение является первым числом, а предел - вторым числом. Это кажущееся противоречие является преднамеренным - оно максимизирует совместимость с устаревшими системами баз данных SQL.


5

Я сделал несколько тестов, и нет разницы в производительности.

Это только для совместимости с другими языками SQL.

Время работы обеих версий одинаково.

Я сделал sqlite db с table1 с 100000 строк. Я запускаю следующий тест

long timeLimitOffset = 0;
long timeLimitComma = 0;
for (int i = 0; i < 100000; i++)
{
   //first version
   timeLimitOffset += SqlDuraction("Select * from table1  order by col1 LIMIT " + (i + 1) + " OFFSET " + (1001 - i) + "");
   // second version
   timeLimitComma += SqlDuraction("Select * from table1 order by col1 LIMIT " + (1001 - i) + " , " + (i + 1) + "");
}

Время меняется на 0,001 секунды


1
почему бы разница в производительности? они такие же!
Абхинав Гауниял
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.