Kolejność operacji w SQL – w jakiej kolejności MySQL wykonuje zapytania?

Zoptymalizuj swoją bazę danych w sposób automatyczny i magiczny.
Kliknij, aby rozpocząć za darmo.

Znajomość kolejności wykonywania zapytań SQL może być bardzo cenna, ponieważ może ułatwić proces pisania nowych zapytań, a także być bardzo korzystna przy próbie optymalizacji zapytań SQL.

Jeśli szukasz skróconej wersji, jest to logiczna kolejność operacji, znana również jako kolejność wykonywania, dla zapytania SQL:

  1. FROM, w tym JOIN
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. Funkcje WINDOW
  6. SELECT
  7. DISTINCT
  8. .

  9. UNION
  10. ORDER BY
  11. LIMIT i OFFSET

Ale rzeczywistość nie jest tak prosta ani łatwa. Jak już wspomnieliśmy, standard SQL definiuje kolejność wykonywania różnych klauzul zapytania SQL. Nowoczesne bazy danych już teraz podważają tę domyślną kolejność, stosując pewne sztuczki optymalizacyjne, które mogą zmienić rzeczywistą kolejność wykonywania zapytań, choć w końcu muszą zwrócić ten sam wynik, jak gdyby wykonywały zapytanie z domyślną kolejnością wykonywania.

Dlaczego miałyby to robić? Cóż, może to być głupie, jeśli baza danych najpierw pobierze wszystkie dane wymienione w klauzuli FROM (w tym JOIN), przed spojrzeniem na klauzulę WHERE i jej indeksy. Tabele te mogą zawierać wiele danych, więc można sobie wyobrazić, co by się stało, gdyby optymalizator bazy danych trzymał się tradycyjnej kolejności operacji zapytania SQL.

Przyjrzyjrzyjmy się każdej z części zapytania SQL zgodnie z ich kolejnością wykonywania.

FROM i JOINs

Tablice określone w klauzuli FROM (w tym JOINs), zostaną ocenione w pierwszej kolejności, aby określić cały zbiór roboczy, który jest istotny dla zapytania. Baza danych połączy dane ze wszystkich tabel, zgodnie z klauzulami JOINs ON, jednocześnie pobierając dane z podzapytań, a nawet może utworzyć kilka tabel tymczasowych, aby przechowywać dane zwrócone z podzapytań w tej klauzuli.

W wielu przypadkach optymalizator bazy danych zdecyduje się najpierw ocenić część WHERE, aby zobaczyć, która część zbioru roboczego może zostać pominięta (najlepiej przy użyciu indeksów), więc nie będzie zbytnio nadmuchiwać zbioru danych, jeśli naprawdę nie musi.

Klauzula WHERE

Klauzula WHERE będzie drugą do oceny, po klauzuli FROM. Mamy już działający zestaw danych, a teraz możemy filtrować dane zgodnie z warunkami w klauzuli WHERE.

Warunki te mogą zawierać odwołania do danych i tabel z klauzuli FROM, ale nie mogą zawierać żadnych odwołań do aliasów zdefiniowanych w klauzuli SELECT, ponieważ te dane i aliasy mogą jeszcze nie „istnieć” w tym kontekście, ponieważ klauzula ta nie została jeszcze obliczona przez bazę danych.

Also, częstą pułapką dla klauzuli WHERE byłaby próba odfiltrowania zagregowanych wartości w klauzuli WHERE, na przykład z tą klauzulą: „WHERE sum(available_stock) > 0”. To stwierdzenie nie powiedzie się podczas wykonywania zapytania, ponieważ agregacje będą oceniane w dalszej części procesu (patrz sekcja GROUP BY poniżej). Aby zastosować warunek filtrowania na danych zagregowanych, należy użyć klauzuli HAVING, a nie klauzuli WHERE.

Klauzula GROUP BY

Teraz, gdy przefiltrowaliśmy zbiór danych za pomocą klauzuli WHERE, możemy zagregować dane według jednej lub więcej kolumn występujących w klauzuli GROUP BY. Grupowanie danych jest w rzeczywistości dzieleniem ich na różne części lub wiadra, gdzie każde wiadro ma jeden klucz i listę wierszy, które pasują do tego klucza. Brak klauzuli GROUP BY jest jak umieszczenie wszystkich wierszy w jednym ogromnym wiadrze.

Po zagregowaniu danych możesz użyć funkcji agregujących, aby zwrócić wartość dla każdej grupy w każdym z wiader. Takie funkcje agregacji obejmują COUNT, MIN, MAX, SUM i inne.

Klauzula HAVING

Teraz, gdy pogrupowaliśmy dane za pomocą klauzuli GROUP BY, możemy użyć klauzuli HAVING, aby odfiltrować niektóre kubełki. Warunki w klauzuli HAVING mogą odwoływać się do funkcji agregujących, więc przykład, który nie zadziałał w klauzuli WHERE powyżej, zadziała równie dobrze w klauzuli HAVING: „HAVING sum(available_stock) > 0”.

Jako że już pogrupowaliśmy dane, w tym momencie nie mamy już dostępu do oryginalnych wierszy, więc możemy stosować warunki tylko do filtrowania całych wiaderek, a nie pojedynczych wierszy w wiaderku.

Jak wspomnieliśmy w poprzednich rozdziałach, aliasy zdefiniowane w klauzuli SELECT również nie mogą być dostępne w tej sekcji, ponieważ nie zostały jeszcze obliczone przez bazę danych (jest to prawdą w większości baz danych).

Funkcje okna

Jeśli używasz funkcji okna, jest to punkt, w którym zostaną one wykonane. Podobnie jak mechanizm grupowania, funkcje Window również wykonują obliczenia na zbiorze wierszy. Główna różnica polega na tym, że podczas używania funkcji okna każdy wiersz zachowa swoją tożsamość i nie zostanie zgrupowany w wiadrze z innymi podobnymi wierszami.

Funkcje okna mogą być używane tylko w klauzuli SELECT lub ORDER BY. Można używać funkcji agregujących wewnątrz funkcji Window, na przykład:

SUM(COUNT(*)) OVER ()

Klauzula SELECT

Teraz, gdy skończyliśmy z usuwaniem wierszy ze zbioru danych i grupowaniem danych, możemy wybrać dane, które chcemy pobrać z zapytania do strony klienta. Możesz użyć nazw kolumn, agregacji i podzapytań wewnątrz klauzuli SELECT. Pamiętaj, że jeśli używasz odwołania do funkcji agregującej, takiej jak COUNT(*) w klauzuli SELECT, jest to jedynie odwołanie do agregacji, która już miała miejsce podczas grupowania, więc sama agregacja nie ma miejsca w klauzuli SELECT, a jest to jedynie odwołanie do jej zestawu wyników.

Słowo kluczowe DISTINCT

Składnia słowa kluczowego DISTINCT jest nieco myląca, ponieważ słowo kluczowe zajmuje miejsce przed nazwami kolumn w klauzuli SELECT. Jednak faktyczna operacja DISTINCT odbywa się po klauzuli SELECT. Podczas używania słowa kluczowego DISTINCT baza danych odrzuci wiersze z zduplikowanymi wartościami z pozostałych wierszy pozostałych po wykonaniu filtrowania i agregacji.

Słowo kluczowe UNION

Słowo kluczowe UNION łączy zestawy wyników dwóch zapytań w jeden zestaw wyników. Większość baz danych pozwala na wybór pomiędzy UNION DISTINCT (co spowoduje odrzucenie zduplikowanych wierszy z połączonego zestawu wyników) lub UNION ALL (co po prostu połączy zestawy wyników bez zastosowania żadnej kontroli duplikacji).

Możesz zastosować sortowanie (ORDER BY) i ograniczanie (LIMIT) na zestawie wyników UNION, w taki sam sposób, w jaki możesz zastosować je na zwykłym zapytaniu.

KlauzulaORDER BY

Sortowanie ma miejsce, gdy baza danych ma gotowy cały zestaw wyników (po filtrowaniu, grupowaniu, usuwaniu duplikatów). Kiedy już to mamy, baza danych może sortować zestaw wyników używając kolumn, wybranych aliasów lub funkcji agregujących, nawet jeśli nie są one częścią wybranych danych. Jedynym wyjątkiem jest użycie słowa kluczowego DISTINCT, które uniemożliwia sortowanie według niewybranej kolumny, ponieważ w takim przypadku kolejność wyników będzie niezdefiniowana.

Możesz wybrać sortowanie danych przy użyciu porządku malejącego (DESC) lub rosnącego (ASC). Kolejność może być unikalna dla każdej z części zamówienia, więc poniższe jest poprawne: ORDER BY firstname ASC, age DESC

LIMIT i OFFSET

W większości przypadków użycia (z wyjątkiem kilku takich jak raportowanie), chcielibyśmy odrzucić wszystkie wiersze oprócz pierwszych X wierszy wyniku zapytania. Klauzula LIMIT, która jest wykonywana po sortowaniu, pozwala nam właśnie to zrobić. Dodatkowo możemy wybrać, od którego wiersza rozpocząć pobieranie danych oraz ile wierszy wykluczyć, używając kombinacji słów kluczowych LIMIT oraz OFFSET. Poniższy przykład spowoduje pobranie 50 wierszy, zaczynając od wiersza #100: LIMIT 50 OFFSET 100

Optymalizuj swoją bazę danych, auto-magicznie.
Kliknij, aby rozpocząć, za darmo.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.