Sqlite LIMIT / OFFSETクエリ


153

Sqliteについて簡単な質問があります。これの違いは何ですか:

Select * from Animals LIMIT 100 OFFSET 50

そして

Select * from Animals LIMIT 100,50

9
コメントで述べたように疑問が解消された場合は、回答としてマークしてください。
ムバシャル

回答:


270

2つの構文形式は、数字が逆になるため、少し混乱します。

LIMIT <skip>, <count>

以下と同等です。

LIMIT <count> OFFSET <skip>

MySQLとPostgreSQLの構文と互換性があります。MySQLは両方の構文形式をサポートしており、そのドキュメントでは、OFFSETを使用した2番目の構文はPostgreSQLとの互換性を提供するためのものであると主張しています。PostgreSQLのドキュメントは、2番目の構文のみをサポートすることを示し、SQLiteのドキュメントは、両方をサポートすることを示し、混乱を避けるために2番目の構文を推奨しています。

ところで、最初にORDER BYを使用せずにLIMITを使用しても、必ずしも意図した結果が得られるとは限りません。実際には、SQLiteは何らかの順序で行を返します。おそらく、ファイルに物理的に格納されている方法によって決定されます。しかし、これは必ずしも必要な順序になっているとは限りません。予測可能な順序を取得する唯一の方法は、ORDER BYを明示的に使用することです。


2
LIMIT <count> OFFSET <skip>より明確です。ありがとうございました。
グイド・モカ

この同様の答えは、行の順序が重要な場合に優れたパフォーマンスと優れたソリューションを提供します。stackoverflow.com/a/28860492/5016333
Rodrigo V

23

後者は、警告が1つある代替構文です。

OFFSETキーワードの代わりにコンマが使用されている場合、オフセットは最初の数値で、制限は2番目の数値です。これは意図的に矛盾しているように見えます。レガシーSQLデータベースシステムとの互換性を最大化します。


5

私はいくつかのテストを行いましたが、パフォーマンスに違いはありません。

これは、他のSQL言語との互換性のためだけのものです。

両方のバージョンの実行時間は同じです。

100000行のtable1でsqlite dbを作成しました。次のテストを実行します

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
パフォーマンスに違いがあるのはなぜですか?彼らは同じです!
Abhinav Gauniyal 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.