Chcę zrozumieć następujące.
Załóżmy, że mam skomplikowane zapytanie z, powiedzmy, złączeniem 5 tabel w grupie według sumowań i sortowania według.
Pomijając wszelkie optymalizacje samego zapytania, np. Indeksy itp.
Czy przynoszą jakieś znaczące korzyści w zakresie wydajności LIMIT
? Zakładam, że wszystkie zapytania (i wyniki) muszą zostać przetworzone przed zastosowaniem LIMIT, więc używając LIMIT do odzyskania podzbioru wyników, czy oferuje to jakąkolwiek znaczącą / zauważalną poprawę?
mysql
performance
join
Jim
źródło
źródło
LIMIT
poprawiają wydajność: Optymalizacja zapytań LIMITOdpowiedzi:
Jeśli chcesz skorzystać z
LIMIT
poprawy wydajności, potrzebujeszLIMIT
wcześniejJOIN
Zasady te mogą przejść długą drogę, jeśli potrafisz je zharmonizować.
Nauczyłem się tych koncepcji, oglądając ten film na YouTube (uważnie słuchaj przez francuski akcent)
Użyłem tych koncepcji, aby odpowiedzieć na bardzo trudne pytanie StackOverflow dotyczące uzyskiwania 40 najlepszych artykułów z niektórych tabel: 12 maja 2011 r .: Pobieranie pojedynczego wiersza z tabeli łączenia .
W mojej odpowiedzi na to pytanie (16 maja 2011 r.) Napisałem następujące zapytanie i dokładnie je przetestowałem:
Proszę zwrócić uwagę na wiersz w zapytaniu za pomocą
LIMIT
To podzapytanie jest zakopane na trzech poziomach. To pozwoliło mi pobrać ostatnie 40 artykułów
LIMIT
. Następnie wykonałem niezbędne połączenia.ZDOBYTA WIEDZA
LIMIT
wewnętrznych podkwerend nie zawsze może być odpowiedzią ze względu na liczność indeksów, zawartość danych i rozmiar zestawu wyników zLIMIT
. Jeśli masz wszystkie „kaczki z rzędu” (pamiętaj o czterech zasadach dotyczących zapytania), możesz uzyskać zaskakująco dobre wyniki.LIMIT
zbierając tylko klucze.źródło
(A [LEFT] JOIN B) LIMIT 100
to jest równoważne z(A LIMIT 100) [LEFT] JOIN (B LIMIT 100)
? Gdzie[LEFT] JOIN
oznacza połączenie zewnętrzne lub wewnętrzne(A LIMIT 100) [LEFT] JOIN B
. Chodzi o to, abyLIMIT
jak najwcześniej określić rozmiar zestawu wyników. Używam równieżLEFT JOIN
zamiast,INNER JOIN
ponieważLEFT JOIN
zachowa kolejność klawiszy po lewej stronie.(A LEFT JOIN B) GROUP BY A.pk LIMIT 100
zwykle można je przepisać jako(A LIMIT 100) LEFT JOIN B GROUP BY A.pk
(brak tutaj WEJŚCIA WEWNĘTRZNEGO, z wewnętrznymi połączeniami nie byłyby równoważne). Przykład Rolando jest właśnie taki.Kiedy zapytanie jest wykonywane, najpierw jest tłumaczone na plan, który składa się z kilku operatorów. Istnieją dwa podstawowe typy operatorów: Blokowanie i Nieblokowanie. Operator nieblokujący pobiera wiersz (lub kilka wierszy) od swojego potomka lub potomków dla każdego żądanego od niego wiersza. Z drugiej strony operator blokujący musi wczytać i przetworzyć cały zestaw wierszy wszystkich swoich elementów potomnych, zanim będzie w stanie wygenerować jakikolwiek wynik.
Sortowanie jest typowym operatorem blokującym. Zatem wybór z zamówieniem według nie korzysta z limitu. Istnieją jednak RDBMS, które mogą wykorzystywać algorytm sortowania, który wymaga mniej pamięci i jest szybszy, gdy podano klauzulę limitu. Wystarczy w tym przypadku po prostu zapisać obecnie pierwsze n wierszy i przenieść je z pamięci w miarę pojawiania się wcześniejszych wierszy. Może to być znaczący wzrost wydajności. Nie jestem jednak w 100% pewien, że MySQL ma tę zdolność.
Tak czy inaczej, nawet sortowanie według limitu musi przetworzyć cały zestaw wierszy wejściowych, zanim będzie mógł wygenerować pierwszy wiersz wyjściowy. Chociaż ten algorytm, jeśli zostanie zaimplementowany, może przyspieszyć sortowanie, jeśli reszta zapytania jest najdroższą częścią, całkowity czas wykonania nie poprawi się znacząco z powodu podanego limitu.
źródło
GROUP BY
może potencjalnie prowadzić do planu, który nie zawiera operatorów blokujących.W moim przypadku mogę powiedzieć Tak , nawet jeśli (nadal) nie rozumiem dlaczego.
Zanotuj czas: 18 sekund. Ta sama prośba z dużym LIMITEM:
Ponad dziesięć razy szybciej !!!
WYJAŚNIJ daje ten sam wynik dla obu żądań.
LIMIT powinien ingerować tylko w celu ograniczenia zestawu wyników (tzn. Jeśli wykonam LIMIT 4, mam tylko pierwsze 4 wiersze powyższego zestawu wyników).
źródło
LIMIT
. Twoje pierwsze zapytanie zostanie uruchomione w ciągu 18 sekund, dając zestaw wyników. Wszystkie dane w drugim zapytaniu są już buforowane w puli buforów InnoDB z powodu pierwszego zapytania, więc oczywiście drugie zapytanie musi być szybsze, nawet jeśli zrestartujesz mysql, uruchom pierwsze zapytanie, uruchom ponownie mysql i uruchom drugie zapytanie, otrzymasz ten sam wynik. . Lepszy wynikLIMIT
może wynikać tylko z: 1)LIMIT
wcześniejJOIN
, 2) LIMIT w kolejności sortowaniaASC
lubDESC
.