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

mysql:bardzo proste SELECT id ORDER BY LIMIT nie użyje INDEX zgodnie z oczekiwaniami (?!)

Wyszukiwanie indeksu odbywa się według wartości , a nie według pozycji . Indeks może wyszukać wartość 2955900, ale nie pytasz o to. Pytasz, aby zapytanie zaczynało się od przesunięcia 2955900. wiersza w tabeli.

Optymalizator nie może zakładać, że wszystkie wartości klucza podstawowego są kolejne. Jest więc całkiem prawdopodobne, że wiersz 2955900 ma znacznie wyższą wartość.

Nawet jeśli wartości klucza podstawowego są kolejne, możesz mieć warunek WHERE, który pasuje tylko na przykład do 45% wierszy. W takim przypadku wartością identyfikatora w 2955900. wierszu będzie droga poza wartość identyfikatora 2955900.

Innymi słowy, wyszukiwanie indeksu o wartości identyfikatora 2955900 nie dostarczy 2955900. wiersza.

Tak więc MySQL nie może używać indeksu do przesunięcia limitu. musi zeskanuj wiersze, aby je policzyć, aż osiągnie przesunięcie + limit wierszy.

MySQL ma optymalizacje związane z LIMIT , ale bardziej chodzi o zatrzymanie skanowania tabeli po osiągnięciu liczby wierszy do zwrócenia. Optymalizator może nadal zgłaszać w planie EXPLAIN, że oczekuje, że może muszę zeskanować cały stół.

Częste nieporozumienie dotyczące INDEKSU SIŁY jest to, że wymusza użycie indeksu. :-)W rzeczywistości, jeśli zapytanie nie może użyj indeksu (lub jeśli dostępne indeksy nie przynoszą żadnych korzyści dla tego zapytania), FORCE INDEX nie ma wpływu.

Odpowiedz na swój komentarz:

Paginacja jest częstą zmorą aplikacji internetowych opartych na danych. Pomimo tego, jak powszechna jest ta funkcja, jej optymalizacja nie jest łatwa. Oto kilka wskazówek:

  • Dlaczego pytasz z przesunięciem 2955900? Czy naprawdę oczekujesz, że użytkownicy będą przeglądać tak wiele stron? Większość użytkowników rezygnuje po kilku stronach (dokładnie ile zależy od typu aplikacji i danych).

  • Zmniejsz liczbę zapytań. Twoja funkcja stronicowania może pobrać pierwsze 5-10 stron, nawet jeśli tylko wyświetla użytkownikowi pierwszą stronę. Buforuj pozostałe strony, zakładając, że użytkownik przejdzie przez kilka stron. Dopiero po przejściu poza zbiór stron w pamięci podręcznej aplikacja będzie musiała wykonać kolejne zapytanie. Możesz nawet buforować wszystkie 10 stron w JavaScript w przeglądarce klienta, więc kliknięcie „Dalej” jest natychmiastowe dla nich (przynajmniej dla tych kilku pierwszych stron).

  • Nie umieszczaj przycisku „Ostatni” w żadnym interfejsie użytkownika, ponieważ ludzie klikną go z ciekawości. Zauważ, że Google ma przycisk „Dalej”, ale nie ma przycisku „Ostatni”. Tak więc sam interfejs użytkownika zniechęca ludzi do uruchamiania nieefektywnych zapytań z wysokimi przesunięciami.

  • Jeśli użytkownik przechodzi do przodu o jedną stronę na raz, użyj najwyższej wartości identyfikatora zwróconej na poprzedniej stronie w klauzuli WHERE zapytania na następnej stronie. Tj. następujące robi użyj indeksu, nawet bez podpowiedzi FORCE INDEX:

    SELECT * FROM thistable WHERE id > 544 LIMIT 20
    



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Uruchom lub zatrzymaj bazę danych mysql za pomocą programowania java

  2. MySQL Visual Studio 2015 Masz już użyteczne połączenie

  3. ColdFusion Parametryzacja zapytania

  4. aktualizacja z dołącz oświadczeniem mysql?

  5. Jak przenieść bazę danych SQLite na serwer WWW na telefonie z systemem Android (Android)