Według rozdziału 9 (Parser i optymalizator), Sasha Pachev , strona 172 książki Understanding MySQL Internal.
oto podział oceny zapytania jako następujące zadania:
- Określ klucze, których można użyć do pobrania rekordów z tabel, i wybierz najlepszy dla każdej tabeli.
- Dla każdej tabeli zdecyduj, czy skanowanie tabeli jest lepsze niż czytanie na kluczu. Jeśli istnieje wiele rekordów pasujących do wartości klucza, zalety klucza są zmniejszone, a skanowanie tabeli staje się szybsze.
- Określ kolejność łączenia tabel, gdy w zapytaniu występuje więcej niż jedna tabela.
- Przepisz klauzule WHERE, aby wyeliminować martwy kod, zmniejszając niepotrzebne obliczenia i zmieniając ograniczenia, tam gdzie to możliwe, aby otworzyć drogę do używania kluczy.
- Wyeliminuj nieużywane tabele ze złączenia.
- Określ, czy można używać kluczy
ORDER BY
i GROUP BY
.
- Spróbuj uprościć podzapytania, a także określić, w jakim stopniu ich wyniki mogą być buforowane.
- Scal widoki (rozwiń odwołanie do widoku jako makro)
Na tej samej stronie jest napisane:
W terminologii optymalizatora MySQL każde zapytanie jest zestawem złączeń. Pojęcie złączenia jest tu stosowane szerzej niż w poleceniach SQL. Zapytanie dotyczące tylko jednej tabeli jest połączeniem zdegenerowanym. Podczas gdy normalnie nie myślimy o czytaniu rekordów z jednej tabeli jako złączenia, te same struktury i algorytmy używane w konwencjonalnych złączeniach działają idealnie, aby rozwiązać zapytanie z tylko jedną tabelą.
EPILOG
Ze względu na obecne klucze, ilość danych i wyrażenie zapytania, połączenia MySQL mogą czasami robić rzeczy dla naszego własnego dobra (lub wrócić do nas) i dawać wyniki, których się nie spodziewaliśmy i których nie możemy szybko wyjaśnić.
O tym dziwactwie pisałem już wcześniej
ponieważ Optymalizator zapytań MySQL może spowodować odrzucenie niektórych kluczy podczas oceny zapytania.
Komentarz @ Phila pomaga mi zobaczyć, jak opublikować tę odpowiedź (+1 za komentarz @ Phila)
Komentarz @ ypercube (+1 również dla tego) jest kompaktową wersją mojego postu, ponieważ Optymalizator zapytań MySQL jest prymitywny. Niestety musi tak być, ponieważ dotyczy zewnętrznych silników pamięci masowej.
WNIOSEK
Jeśli chodzi o twoje pytanie, Optymalizator zapytań MySQL określałby wskaźniki wydajności każdego zapytania po jego zakończeniu
- liczenie wierszy
- wybieranie kluczy
- masowanie przerywanych zestawów wyników
- O tak, robię rzeczywiste DOŁĄCZ
Prawdopodobnie musiałbyś wymusić kolejność wykonywania przez przepisanie (refaktoryzację) zapytania
Oto pierwsze zadane przez Ciebie zapytanie
select count(*)
from table1 a
join table2 b
on b.key_col=a.key_col
where b.tag = 'Y';
Spróbuj przepisać go, aby najpierw ocenić GDZIE
select count(*)
from table1 a
join (select key_col from table2 where tag='Y') b
on b.key_col=a.key_col;
To zdecydowanie zmieni plan EXPLAIN. Może dawać lepsze lub gorsze wyniki.
Kiedyś odpowiedziałem na pytanie w StackOverflow, w którym zastosowałem tę technikę. EXPLAIN był przerażający, ale występ był dynamitem. Działa to tylko z powodu obecności poprawnych indeksów i zastosowania LIMIT w podzapytaniu .
Podobnie jak w przypadku cen akcji, jeśli chodzi o zapytania i próby ich wyrażenia, obowiązują ograniczenia, wyniki mogą się różnić, a wyniki w przeszłości nie wskazują przyszłych wyników.