Kihagyás

Adatvezérelt rendszerek

Lekérdezés optimalizálás célja

  • időre optimalizálunk
  • Válaszidő befolyásoló tényezői
    • I/O költség
      • ez a legmeghatározóbb
      • Moore törvény nem igaz
    • CPU használat
      • komplex lekérdezéseknél, összetett számításoknál
    • Memória használat → Cache hatása miatt
  • adatbázis végzi az optimalizálást
    • statisztikák alapján
      • költség becslés = válaszidő (CPU + I/O idő)
    • triviális terv → ezeket NEM kell optimalizálni, mert az több idő lenne
      • egyszerűbb lekérdezéshez egyértelműen generálható
      • szabály alapú lekérdezési tervek
    • ha nem készíthető triviális terv
      • összetett optimalizálás
        1. fázis
          • egyszerű szabály alapú átalakítások (hash join-t preferál)
          • ha így már adott költség alatti, akkor végrehajtja
        2. fázis
          • kibővített átalakítások
          • ha így már adott költség alatti, akkor végrehajtja
        3. fázis → párhuzamos végrehajtás vizsgálata
  • lekérdezés feldolgozás menete
    • elemző (parser) → optimalizáló → sorfordító → végrehajtó
    • elemző: szövegből logikai tervet készít (lekérdezés fordítása)
    • optimalizáló: fizikai terv készítése, táblák bejárása és összekapcsolása
    • sorfordító: I/O műveletekre leképzi
    • végrehajtó: végrehajtja
  • logikai végrehajtási terv
    • elemző fa
      • relációk (levél elemek)
      • műveletek (csomópontok) pl join, szűrés
        • descartes-szorzat, projekció, szelekció, összekapcsolás, ismétlődés szűrése, csoportosítás, rendezés
      • adatok lentről fölfele "áramlanak"
    • elemző fa átalakítása
      • cél: optimális logikai terv kialakítása, fizikai végrehajtási terv keresési terének vágása
      • alapkoncepciók:
        • kiválasztás műveletek lefele mozgatása (szűrés lefele, hogy kevesebb adattal kelljen dolgozni!)
        • join operátorok használata (direkt szorzatot kerüljük)
        • join operátorok egyik attribútuma mindig tábla
      • kiválasztások leírása a diasorban!
  • fizikai végrehajtási terv
    • algoritmusok konkretizálása
    • tervek szabály alapján vagy költségbecslés alapján
    • join algoritmusok:
      • nested loop join → egymásba ágyazott kettős for ciklus
        • I/O költség → O(blokk_szám_1 * blokk_szám_2)
        • tetszőleges méretű táblák esetén működik
      • hash join
        • kisebb reláció beolvasása
        • vödrös hash építése a memóriában (kulcs a join operátorban szereplő oszlop)
        • a nagyobbik reláció beolvasása, kapcsolódó rekordok keresése a vödrös hashben
        • I/O költség → O(blokk_szám_1 + blokk_szám_2)
        • negatívumok: el kell férnie a táblának a memóriában, csak egyenlőség alapon lehet keresni
      • sort merge join
        • mindkét reláció beolvasása a memóriába, majd rendezzük kulcs szerint
        • összefésüljük a 2 listát
        • kis méretű relációk esetén jó, index kell a rendezés miatt
        • I/O költség → O(blokk_szám_1 + blokk_szám_2)
    • tábla elérési módok
      • 2 kategória:
        • teljes átvizsgálás → mindet felolvassuk a disk-ről (kis táblák esetén, ha minden rekordra szükség van)
        • index alapú átvizsgálás → szűrés esetén, rendezés megvalósításakor
      • table scan → ha nincs semmilyen index, szűrési feltételt is kiértékeli
      • clustered index scan → nyalábolt adatolvasás
        • adatblokkok index szerint rendezve (primary key mentén jön létre automatikusan MSSQL-ben)
        • table scan helyett ezt preferálja!
      • nonclustered index scan → =-ség jellegű kiértékelésekkor
      • clustered/nonclustered index seek
        • index scan-hez hasonló
        • B*fa leveleinek bejárása kezdőemetől
        • kisebb, nagyobb, between kiértékelésére
      • covered index
        • B*fa levelének bővítése oszlopokkal, nem kell kiolvasni a tényleges rekordot
    • indexek
      • egyszerű, összetett, clustered (memórián is olyan sordban van, csak 1clustered index lehet)
      • clustered és nonclustered index együtt → nonclustered mutat a clustered-re és az meg a disk-re
      • nézetek is indexelhetőek MSSQL-ben
    • lekérdezési tervek cach-e → plan cache
      • ha ugyanolyan struktúrájú lekérdezés jön, és ha statisztikák nem változtak
      • tárolt eljárásra előre vannak elkészített lekérdezési tervek
        • itt megadhatjuk, hogy mire optimalizáljunk
  • általános tanácsok
    • statisztikák legyenek naprakészek (ne kapcsoljuk őket ki!)
    • lekérdezés struktúrája
      • gondolkodjuk az adatbázis fejébel
      • többféleképp megfogalmazható dolgoknál
      • minél egyszerűbben írjuk le, annál jobb!
      • select * -ot kerüljük! (nem tudja kihasználni az indexelést)
    • inkább join mint in / not in, exists / not exist
    • exists helyett inkább in
    • nézeteket kerüljük ha lehet
    • kerüljük a vagy feltételeket → union all
    • kerüljük az al-lekérdezéseket
    • indexek
      • sématervezéskor már gondoljunk erre!
      • összetett indexnél a hierarchia számít
      • matematikai műveleteket kerüljük, mert elronthatja az indexelést (price+10<100 helyett price<90 legyen)
    • függvények használata
      • select listában lehet
      • where feltételben ne használjuk!
  • MongoDB
    • indexelés meghatározó (csak keresési célt szolgál, mivel nincs join)
    • index típusok
      • egyszerű & összetett
      • unique index
      • tömbök tartalmát is indexeli
      • beágyazott dokumentumokat is indexeli
    • indexet _id-n kívül létre kell hozni
    • nem használ statisztokákat
    • mindet elkezdi lehajtani, amelyik első 101db-ot visszaadja → azt fogja használni
    • optimalizáló lépések
      • szűrés előre mozgatás
      • sklp és limit előre mozgatás (projekció elé)
      • összevonás (limit+limit, skip+skip)
    • van terv cache
      • csak a struktúrája szerepel, hogy mire szűrtünk azt pl nem (csak a mezők neve, az érték nem)
    • query.explain() → megmutatja a tervét