Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Zapytanie MySQL z limitem i dużym przesunięciem trwa wiecznie

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:

  1. Prowadź wszystkie normalne planowanie zapytań tak, jakby LIMIT klauzuli nie było
  2. Przeglądaj wyniki, aż dojdziemy do żądanego indeksu
  3. Zacznij zwracać wyniki

Co to oznacza, jeśli zrobisz LIMIT 10000, 10 , zostanie zinterpretowane jako:

  1. Pobierz pierwsze 10 000 wyników i zignoruj ​​je
  2. 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.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Status użytkownika online offline - problem ze statusem offline

  2. Wyzwania związane ze skalowaniem bazy danych Moodle MySQL

  3. Zapytanie o liczbę tabel, które mam w MySQL

  4. Hibernacja:Zakleszczenie podczas próby uzyskania blokady

  5. Wstrzyknięcie SQL, które omija mysql_real_escape_string()