SQL műveleti sorrend – Milyen sorrendben hajtja végre a MySQL a lekérdezéseket?

Optimalizálja adatbázisát, auto-mágikusan.
Kattintson az indításhoz, ingyenesen.

Egy SQL-lekérdezés műveletsorrendjének ismerete nagyon értékes lehet, mivel megkönnyítheti az új lekérdezések írását, ugyanakkor nagyon hasznos lehet egy SQL-lekérdezés optimalizálásakor is.

Ha a rövid változatot keresi, ez egy SQL-lekérdezés logikai műveletsorrendje, más néven végrehajtási sorrendje:

  1. FROM, beleértve a JOIN-okat
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. WINDOW függvények
  6. SELECT
  7. DISTINCT
  8. .

  9. UNION
  10. ORDER BY
  11. LIMIT és OFFSET

A valóság azonban nem ilyen egyszerű és nem is ilyen egyszerű. Mint említettük, az SQL-szabvány meghatározza a különböző SQL-lekérdezési záradékok végrehajtási sorrendjét. Azt mondtuk, hogy a modern adatbázisok már megkérdőjelezik ezt az alapértelmezett sorrendet néhány optimalizációs trükk alkalmazásával, amelyek megváltoztathatják a tényleges végrehajtási sorrendet, bár a végén ugyanazt az eredményt kell visszaadniuk, mintha a lekérdezést az alapértelmezett végrehajtási sorrendben futtatnák.

Miért tennék ezt? Nos, butaság lehet, ha az adatbázis először lekérdezné a FROM záradékban említett összes adatot (beleértve a JOIN-okat is), mielőtt megnézné a WHERE záradékot és annak indexeit. Ezek a táblák rengeteg adatot tartalmazhatnak, így elképzelhetjük, mi történne, ha az adatbázis optimalizálója ragaszkodna az SQL-lekérdezés hagyományos műveletsorrendjéhez.

Nézzük meg az SQL-lekérdezés egyes részeit a végrehajtási sorrendjük szerint.

FROM és JOIN-ok

A FROM záradékban megadott táblákat (beleértve a JOIN-okat is), először kiértékeli, hogy meghatározza a lekérdezés szempontjából releváns teljes munkakészletet. Az adatbázis a JOINs ON záradékoknak megfelelően összevonja az összes táblából származó adatokat, miközben az allekérdezésekből is lekérdezi az adatokat, és esetleg létrehoz néhány ideiglenes táblát az ebben a záradékban szereplő allekérdezésekből visszaadott adatok tárolására.

Az adatbázis optimalizálója azonban sok esetben úgy dönt, hogy először a WHERE részt értékeli ki, hogy megnézze, a munkakészlet mely része hagyható ki (lehetőleg indexek segítségével), így nem fogja túlságosan felfújni az adathalmazt, ha nem feltétlenül szükséges.

WHERE záradék

A WHERE záradék a FROM záradék után másodikként kerül kiértékelésre. Megvan a működő adathalmaz, és most már szűrhetjük az adatokat a WHERE záradékban szereplő feltételek szerint.

Ezek a feltételek tartalmazhatnak hivatkozásokat a FROM záradékban szereplő adatokra és táblákra, de nem tartalmazhatnak hivatkozásokat a SELECT záradékban meghatározott aliasokra, mivel ezek az adatok és ezek az aliasok még nem “létezhetnek” ebben a kontextusban, mivel azt a záradékot még nem értékelte ki az adatbázis.

A WHERE záradék gyakori buktatója az is, hogy a WHERE záradékban megpróbáljuk kiszűrni az összesített értékeket, például ezzel a záradékkal: “WHERE sum(available_stock) > 0”. Ez az utasítás meghiúsítja a lekérdezés végrehajtását, mivel az aggregációk a folyamat későbbi szakaszában kerülnek kiértékelésre (lásd a GROUP BY részt alább). Ha szűrési feltételt akarunk alkalmazni az aggregált adatokra, akkor a HAVING záradékot kell használnunk, nem pedig a WHERE záradékot.

GROUP BY záradék

Most, miután a WHERE záradékkal megszűrtük az adathalmazt, a GROUP BY záradékban megjelenő egy vagy több oszlop szerint aggregálhatjuk az adatokat. Az adatok csoportosítása tulajdonképpen az adatok különböző darabokra vagy vödrökre való felosztását jelenti, ahol minden vödörnek van egy kulcsa és az adott kulcsnak megfelelő sorok listája. Ha nincs GROUP BY záradék, az olyan, mintha az összes sort egyetlen hatalmas vödörbe tennénk.

Amikor már összevontuk az adatokat, most már használhatjuk az aggregációs függvényeket, hogy minden egyes vödörhöz csoportonkénti értéket adjunk vissza. Ilyen aggregációs függvények például a COUNT, MIN, MAX, SUM és mások.

HAVING záradék

Most, miután a GROUP BY záradék segítségével csoportosítottuk az adatokat, a HAVING záradék segítségével kiszűrhetünk néhány vödröt. A HAVING záradékban szereplő feltételek hivatkozhatnak az aggregációs függvényekre, így az a példa, amelyik a fenti WHERE záradékban nem működött, a HAVING záradékban tökéletesen fog működni: “HAVING sum(available_stock) > 0”.

Mivel már csoportosítottuk az adatokat, ezen a ponton már nem tudunk hozzáférni az eredeti sorokhoz, így csak teljes vödrök szűrésére alkalmazhatunk feltételeket, a vödrökben lévő egyes sorok szűrésére nem.

Amint az előzőekben említettük, a SELECT záradékban definiált aliasok sem érhetők el ebben a szakaszban, mivel azokat az adatbázis még nem értékelte ki (ez a legtöbb adatbázisra igaz).

Window függvények

Ha Window függvényeket használunk, akkor ez az a pont, ahol azok végrehajtásra kerülnek. A csoportosítási mechanizmushoz hasonlóan az ablakfüggvények is számítást végeznek egy sorhalmazon. A fő különbség az, hogy Window függvények használata esetén minden sor megtartja saját identitását, és nem kerül csoportosításra más hasonló sorok vödrébe.

A Window függvények csak a SELECT vagy az ORDER BY záradékban használhatók. Az ablakfüggvényeken belül használhat aggregációs függvényeket, például:

SUM(COUNT(*)) OVER ()

SELECT klauzula

Most, hogy végeztünk az adathalmaz sorainak elvetésével és az adatok csoportosításával, kiválaszthatjuk azokat az adatokat, amelyeket a lekérdezésből az ügyféloldalra szeretnénk elhozni. A SELECT záradékon belül használhatunk oszlopneveket, aggregációkat és alkérdéseket. Ne feledje, hogy ha egy aggregációs függvényre, például COUNT(*)-ra való hivatkozást használ a SELECT záradékban, akkor az csupán egy olyan aggregációra való hivatkozás, amely már megtörtént a csoportosításkor, tehát maga az aggregáció nem történik meg a SELECT záradékban, hanem ez csak annak eredményhalmazára való hivatkozás.

DISTINCT kulcsszó

A DISTINCT kulcsszó szintaxisa kissé zavaró, mert a kulcsszó a SELECT záradékban az oszlopnevek előtt foglal helyet. A tényleges DISTINCT művelet azonban a SELECT után következik. A DISTINCT kulcsszó használatakor az adatbázis a duplikált értékeket tartalmazó sorokat elveti a szűrés és az aggregálás után megmaradt sorok közül.

UNION kulcsszó

Az UNION kulcsszó két lekérdezés eredményhalmazát egyesíti egyetlen eredményhalmazzá. A legtöbb adatbázis lehetővé teszi, hogy válasszunk az UNION DISTINCT (amely a duplikált sorokat elveti az egyesített eredményhalmazból) vagy az UNION ALL (amely csak egyesíti az eredményhalmazokat a duplikáció ellenőrzése nélkül) között.

Az UNION eredményhalmazon ugyanúgy alkalmazhatunk rendezést (ORDER BY) és korlátozást (LIMIT), mint egy hagyományos lekérdezésen.

ORDER BY záradék

A rendezés akkor történik, amikor az adatbázis már rendelkezik a teljes eredményhalmazzal (szűrés, csoportosítás, duplikáció eltávolítás után). Ha ez megvan, akkor az adatbázis már képes az eredményhalmazt oszlopok, kiválasztott aliasok vagy aggregációs függvények segítségével rendezni, még akkor is, ha ezek nem részei a kiválasztott adatoknak. Az egyetlen kivétel a DISTINCT kulcsszó használata, amely megakadályozza a nem kiválasztott oszlopok szerinti rendezést, mivel ebben az esetben az eredményhalmaz sorrendje meghatározatlan lesz.

Választhatjuk, hogy az adatokat csökkenő (DESC) vagy növekvő (ASC) sorrendben rendezzük. A sorrend minden egyes sorrendi résznél egyedi lehet, így a következők érvényesek: ORDER BY keresztnév ASC, életkor DESC

LIMIT és OFFSET

A legtöbb felhasználási esetben (kivéve néhányat, például a jelentéskészítést) a lekérdezés eredményének első X sora kivételével minden sort el akarunk dobni. A LIMIT záradék, amelyet a rendezés után hajtunk végre, éppen ezt teszi lehetővé számunkra. Ezenkívül a LIMIT és OFFSET kulcsszavak kombinációjával kiválaszthatjuk, hogy melyik sorból kezdjük el az adatok lekérdezését, és hányat zárjunk ki. A következő példa 50 sort fog lekérni a 100. sorral kezdődően: LIMIT 50 OFFSET 100

Optimalizálja adatbázisát, auto-varázslatosan.
Kattintson az indításhoz, ingyenesen.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.