LIMIT z przesunięciem działa bardzo wolno w większości baz danych (znalazłem niektóre dokumentacja w tym celu dla MySQL i staram się znaleźć naprawdę dobry artykuł, który przeczytałem jakiś czas temu, wyjaśniający to dla SQLite). Powodem jest to, że generalnie jest to zaimplementowane mniej więcej tak:
- Prowadź wszystkie normalne planowanie zapytań tak, jakby
LIMIT
klauzuli nie było - Przeglądaj wyniki, aż dojdziemy do żądanego indeksu
- Zacznij zwracać wyniki
Co to oznacza, jeśli zrobisz LIMIT 10000, 10
, zostanie zinterpretowane jako:
- Pobierz pierwsze 10 000 wyników i zignoruj je
- Daje kolejne 10 wyników
Istnieje trywialna optymalizacja, w której możesz przynajmniej użyć indeksu dla pierwszych 10 000 wyników, ponieważ nie dbasz o ich wartości, ale nawet w tym przypadku baza danych nadal musi przejść przez 10 000 wartości indeksu, zanim poda 10 wyników. Mogą istnieć dalsze optymalizacje, które mogą to poprawić, ale w ogólnym przypadku nie chcesz używać LIMIT
z przesunięciem dla dużych wartości .
Najbardziej wydajnym sposobem obsługi stronicowania, o którym wiem, jest śledzenie ostatniego indeksu, więc jeśli pierwsza strona kończy się na id = 5
, a następnie ustaw następny link ma WHERE id > 5
(z LIMIT x
oczywiście).
EDYCJA:Znaleziono artykuł dotyczący SQLite . Gorąco polecam to przeczytanie, ponieważ wyjaśnia The Right Way™, aby robić rzeczy w SQL. Ponieważ ludzie z SQLite są naprawdę mądrzy i inne bazy danych mają ten sam problem, zakładam, że MySQL implementuje to w podobny sposób.