2010-07-24 12 views
122

Mam proste pytanie z Sqlite. Jaka jest różnica między tym:Sqlite LIMIT/OFFSET query

Select * from Animals LIMIT 100 OFFSET 50 

i

Select * from Animals LIMIT 100,50 
+9

Proszę oznaczyć ją jako odpowiedź, jeśli otworzyło swoje wątpliwości, jak wspomniano w komentarzach. –

Odpowiedz

211

dwóch form składniowych są nieco mylące, ponieważ odwrócić numery:

LIMIT <skip>, <count> 

jest równoznaczne z:

LIMIT <count> OFFSET <skip> 

Jest kompatybilny ze składnią MySQL i PostgreSQL. MySQL obsługuje obie formy składni, a jego docs twierdzi, że druga składnia z OFFSET miała zapewnić kompatybilność z PostgreSQL. PostgreSQL docs pokazuje, że obsługuje tylko drugą składnię, a SQLite's docs pokazuje, że obsługuje obie, zalecając drugą składnię, aby uniknąć nieporozumień.

Nawiasem mówiąc, używanie LIMIT bez wcześniejszego użycia ORDER BY może nie zawsze dawać oczekiwanych rezultatów. W praktyce SQLite zwróci wiersze w pewnej kolejności, prawdopodobnie określone przez to, jak są fizycznie przechowywane w pliku. Ale to niekoniecznie oznacza, że ​​jest w takiej kolejności, w jakiej chcesz. Jedynym sposobem uzyskania przewidywalnej kolejności jest jednoznaczne użycie ZAMÓWIENIA.

+0

Hej! Dziękuję Ci bardzo! Usunąłeś moją wątpliwość – Pablo

+2

'LIMIT OFFSET ' jest bardziej przejrzysty. Dziękuję Ci. –

+0

Podobna odpowiedź ma dobre rozwiązanie z dobrą wydajnością, jeśli kolejność wierszy ma znaczenie. http://stackoverflow.com/a/28860492/5016333 –

19

Ten ostatni jest alternatywą składni jednym zastrzeżeniem:

Jeśli przecinek jest używany zamiast OFFSETU słowo kluczowe, to przesunięcie jest pierwsza liczba a granica jest druga liczba . Ta pozorna sprzeczność jest zamierzona - zapewnia ona zgodność ze starszymi wersjami baz danych SQL .

+0

Dziękuję bardzo! – Pablo

6

Zrobiłem kilka testów i nie ma różnicy w wydajności.

To jest tylko dla kompatybilności z innymi językami sql.

Czas działania obu wersji jest taki sam.

Zrobiłem sqlite db z table1 z 100000 wierszy. Biegnę następny test

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) + ""); 
} 

Times różna dla 0.001 drugiego

+0

dlaczego mieliby wystąpić różnice w wydajności? są takie same! –