( asch | 2020. 10. 12., h – 10:19 )

> És ezt hogyan csináljam?

Ilyesmi:

SQL:

Select * from salary where salary>120000

Programban a resultsettel ezt csinálod:


select * from titles where employee_id in (${resultset->id vesszővel elválasztott lista})

És így tovább. Tehát az al-lekérés eredményét áthajtod a programon. Ez szinte mindig antipattern, nem is végleges megoldásnak javaslom én sem, hanem azért hogy meg tudd mérni, hogy melyik része meddig tart, és akkor azon tudsz gondolkodni, hogy mit lehetne optimalizálni.

Abban a szélsőséges esetben viszont, ha az adatbázis által megálmodott lekérdezés tervnél egyértelműen okosabbat is ki tudsz találni, akkor akár még jobb is lehet egy ilyen megoldás. Hasonlóképpen, ha az al-lekérések eredményeit cache-eled egy korábbi lekérdezésből, vagy valami ilyesmi, akkor is ésszerű lehet ilyet csinálni.

> Ebben lehet, hogy igazad van, csak épp nem piszkálhatok hozzá a szerkezethez.

Ha nem lehet hozzányúlni a szerkezethez, akkor simán lehet, hogy ezek a lekérdezési idők nagyjából kiadják a rendszer lehetőségeit. Gondold meg, hogy ha nincsen célirányos index, akkor a teljes adatmennyiséget végig kell nyálazni. 150 mega (a legnagyobb tábla becsült mérete) nem annyira sok, de ha arra a szűrésre sok pozitív találat van, akkor nagyon sok kulcsot kell lekérni a másik táblából, ami minden esetben egy fában keresés lesz. Hozzávéve, hogy esetleg a cache is rosszul használódik akár még ki is jöhet, hogy ezen az adatszerkezeten ez ennyi és kész. Én leprogramoznám ugyanezt a lekérést Java-ban a megfelelő indexeket TreeMap-ekbe téve, és ha hasonló idők jönnek ki, akkor ez ennyi és kész. (Mármint csak akkor csinálnék ilyet, ha nagyon fontos lenne az egész, és ráadásul jobb ötletem sem lenne. Benchmarknak, hogy mit lehet kihozni a vasból. Hasonlóan a megfelelő indexeket is felvenném még akkor is, ha a végső produktba valamiért nem lehet beletenni ezeket: szintén benchmarknak.)

> Végrehajtási terv alatt mit értesz, az explaint?

Azt hiszem úgy hívják. Olyanok vannak benne, hogy először ehhez az indexhez fogok nyúlni, és ezeket a feltételeket tudom szűrni vele. Utána az eredményt ezzel a másik táblával összejoinolom. És így tovább.

Adatbázisok tárgyból mi annó úgy tanultuk, hogy az SQL egy leíró nyelv, amivel ilyen elméleti konstrukciókat lehet leírni, amikkel deklaráljuk, hogy mit akarunk látni, de egyáltalán nem tudunk általa a lekérdezés végrehajtásának mikéntjére hatni. Legalábbis ez az elv. Az adatbázis a lekérdezésből egy absztrakt adatszerkezetet csinál, amit aztán transzformálgat, ahogy neki tetszik. Tehát két ekvivalens lekérdezésnek ha teljesen más is a formája, akkor is ugyanarra a lekérdezési tervre fordul le többnyire. Hasonlóan az optimalizáló fordítókhoz, illetve tulajdonképpen ez is az. Az olyanok viszont már számítanak, hogy a feltételeket hogyan fogalmazzuk meg, például egy indokolatlan egyenlőség helyett "like" használat le tudja rontani a teljesítményt és hasonlók.

Na most a végrehajtási terv az már egy imperatív dolog, és ha tudod, hogy mekkorák a részeredmények, akkor az alapján már lehet futásidőt is becsülni. Illetve a részlet lekéréseket külön-külön is tudod futtatni, tudod mérni (sőt, szerintem van ilyen feature-e az explain-nek, hogy a mérési eredményeket is beleírja). És akkor látszani fog, hogy mi lassú, hol megy el az idő. Ha van benne négyzetes skálázódás, illetve olyan, hogy a szűrést a rossz oldalon kezdi, akkor azokon lehet gondolkodni, hogy hogy lehet kikerülni. Ha meg nincs, akkor ennyit tud a vas, és mégiscsak a tárolási szerkezetet meg kell változtatni.