Részletesebb információk az alábbi Oracle dokumentációkban találhatók: Oracle Documentation 12c book -> SQL Tuning Guide Hintekről: book -> SQL Language Reference -> 2. Basic Elements of Oracle SQL -> Comments -> Hints Az eddigi pédákban szereplő OPERATION és OPTION műveletek és jelentésük a (PLAN_TABLE-ből) ------------------------------------------------------------------------------------------ TABLE ACCESS FULL -- a tábla összes sorának (blokkjának beolvasása) HASH -- hash clusteren levő táblák elérése a hash függvény alapján CLUSTER -- index clusteren levő táblák elérése BY INDEX ROWID -- a tábla sorainak elérése a sorazonosítók alapján BY USER ROWID -- a felhasználó által megadott sorazonosító alapján BY GLOBAL INDEX ROWID -- globális partícionált indexből vett sorazonosítók alapján BY LOCAL INDEX ROWID -- lokális partícionált indexből vett sorazonosítók alapján PARTITION RANGE ALL -- összes partíció olvasása PARTITION RANGE SINGLE -- egyetlen partíció olvasása PARTITION RANGE ITERATOR -- több partíció olvasása INLIST ITERATOR -- műveletek ismétlése SORT AGGREGATE -- összesítés, csoportosítás (GROUP BY) nélkül UNIQUE -- ismétlődések megszüntetése, rendezés alapú algoritmussal GROUP BY -- rendezés alapú csoportosítás JOIN -- előzetes rendezés a későbbi join-hoz ORDER BY -- rendezés ORDER BY miatt HASH UNIQUE -- ismétlődések megszüntetése, hash alapú algoritmus HASH GROUP BY -- csoportok képzése hash alapú algoritmussal UNION-ALL -- két sorhalmaz uniója UNION -- unió ismétlődések megszűntetésével MINUS -- két sorhalmaz különbsége INTERSECTION -- metszet CONCATENATION -- unió képzése két vagy több sorhalmazból VIEW -- alkérdés sorainak előállítása FILTER -- egy sorhalmaz szűrése NESTED LOOPS -- join művelet NESTED LOOP algoritmussal HASH JOIN -- hasítás alapú join algoritmus HASH JOIN OUTER -- külső join HASH JOIN ANTI -- baloldali antijoin (NOT EXISTS vagy NOT IN esetén) HASH JOIN RIGHT -- jobboldali antijoin HASH JOIN ANTI NA -- NULL aware, vagyis NULL is előfordulhat az antijoin során HASH JOIN SEMI -- baloldali semijoin (EXISTS vagy IN esetén) MERGE JOIN -- JOIN művelet, előzetesen rendezett sorhalmazok összefuttatásával MERGE JOIN ANTI MERGE JOIN SEMI INDEX FULL SCAN -- teljes index végigolvasása növekvő sorrendben INDEX FULL SCAN DESCENDING -- teljes index végigolvasása csökkenő sorrendben INDEX FAST FULL SCAN -- teljes index végigolvasása, egyszerre több blokkot olvasva, nem sorrendben INDEX RANGE SCAN -- intervallum keresés növekvő sorrendben (DESCENDING -> csökkenő) INDEX UNIQUE SCAN -- egyedi érték keresés az indexben INDEX SKIP SCAN -- több oszlopos index olvasása, az első oszlopok ismerete nélkül AND-EQUAL -- két sorazonosító halmaz metszetét képezi BITMAP INDEX SINGLE VALUE -- egyetlen bitvektor visszaadása BITMAP INDEX RANGE SCAN -- több bitvektor visszaadása (több egyenlőséges feltétel) BITMAP AND -- bitmapek közötti logikai művelet BITMAP OR -- bitmapek közötti logikai művelet BITMAP MERGE -- több bitvektor összefésülése egyetlen bitvektorrá BITMAP CONVERSION TO ROWIDS -- bitvektor átalakítása sorazonosítókká BITMAP CONVERSION FROM ROWIDS -- sorazonosítók átalakítása bitvektorrá BITMAP CONVERSION COUNT -- ha csak a sorazonosítók számára van szükség, azok megszámolása INLIST ITERATOR -- műveletek ciklusban ================================================================================= Hintek (tippek) adása az optimalizálónak --------------------------------------------------------------------------------- A hintek speciális megjegyzések, amelyek utasításokat adnak az optimalizálónak. Mindig csak arra az utasitás blokkra vonatkoznak, amiben szerepelnek. Az utasitás blokk a következők egyike lehet: - Egyszerű SELECT, UPDATE, DELETE INSERT utasítás - Komplex utasításban a külső utasitás vagy a SELECT (pl. INSERT /*+ hintek */ ... SELECT /*+ hintek */ ...) - Összetett utasitás egyik része (pl. SELECT /*+ hintek */ ... UNION SELECT /*+ hintek*/ ... ) A hint csak közvetlenül az utasitás kulcsszava után jöhet megjegyzésben. [SELECT|DELETE|UPDATE|INSERT] /*+ tipp_lista */ (a '+' előtt nincs szóköz !!! ) A hinteket szóköz választja el egymástól. Ha hiba van a hint-ben az oracle figyelmen kívül hagyja, de nem jelez hibát. Példák: SELECT /*+ tipp lista */ * FROM emp WHERE ... SELECT /*+ tipp lista */ * FROM emp WHERE deptno IN ( SELECT /*+ tipp lista */ deptno FROM ...) INSERT /*+ tipp lista */ ... SELECT /*+ tipp lista */ ... SELECT /*+ tipp lista */ ... UNION SELECT /*+ tipp lista */ ... Fontos! Ha minősített tábla szerepel a lekérdezésben akkor a sémanevet (nikovits) ne adjuk meg, használjunk aliast, pl. SELECT /*+ full(c) */ ... FROM nikovits.cikk c ... A legfontosabb hintek: (a teljes lista -> SQL Reference) -------------------------------------------------------- ALL_ROWS Költseg alapú optimalizalast valaszt es azon belul is a teljes lekerdezesre optimalizal. FIRST_ROWS(n) A legjobb valaszidőre optimalizál. Az lekérdezés első n sorát a lehető leggyorsabban próbálja meg visszaadni. Ha nem adjuk meg n-et, akkor n=1-et tekinti. FULL(tábla) vagy FULL(alias név) Nem hasznal indexet, hanem full table scant. CLUSTER(tábla) Csak index clusteren lévő tábláknál van értelme. HASH(tábla) Csak hash clusteren lévő táblánál van értelme. INDEX(tábla [indexlista]) A tablat index alapjan eri el. Ha nem adunk meg index nevet (vagy többet adunk meg) akkor a legolcsóbb költségű indexet (a felsoroltakbol) használja. INDEX_ASC(tábla [indexlista]) Növekvő sorrendben eri el az index bejegyzeseket. INDEX_DESC(tábla [indexlista]) Megfordítja az alapértelmezett index bejárási sorrendet. Csökkenő sorrendben éri el az index bejegyzéseket. (Illetve csökkenő indexnél növekvőben.) INDEX_COMBINE(tabla [indexlista]) Bitmap indexek segítségével próbálja meg elérni az adatokat. INDEX_FFS(tábla [indexlista]) Fast full index scan-re utasítja az optimalizálót a teljes tábla olvasás helyett. INDEX_JOIN(tábla [indexlista]) Több index használatával és a sorazonosítók join-olásával érje el a táblát. AND_EQUAL(tábla [indexlista]) Több index egyidejű használatával éri el a táblát, úgy, hogy az indexekből visszakapott sorazonosítók metszetét képezi, majd ezekek követve olvassa be a sorokat. NO_INDEX(tábla [indexlista]) A megadott indexek használatáról lebeszéli az optimalizálót. NO_INDEX_FFS(tábla [indexlista]) A megadott indexek használatáról lebeszéli az optimalizálót. NO_EXPAND Ha a lekérdezésben OR vagy IN szerepel, akkor az optimalizáló hajlamos az egyes esetek szerint külön-külön keresni (pl. index használatával). Ez a hint erről beszéli le az optimalizálót. USE_CONCAT Az OR feltételekből uniót hoz létre, és így hajtja végre a lekérdezést. LEADING(táblalista) A megadott táblákkal kezdi a lekérdezés végrehajtását. (Hasonló az ORDERED-hez) ORDERED A táblákat abban a sorrendben fogja join-olni, ahogy azok a FROM után szerepelnek. USE_HASH(táblalista) A megadott táblákat hash join-nal join-olja a többi adatforráshoz. NO_USE_HASH(táblalista) Az előző ellentéte. USE_NL(táblalista) A megadott táblákat nested looppal join-olja a többi adatforráshoz. A megadott tábla lesz a belső ciklus táblája. NO_USE_NL(táblalista) Az előző ellentéte USE_MERGE(táblalista) A megadott táblákat sort-merge-el join-olja a többi adatforráshoz. NO_USE_MERGE(tablalista) Az előző ellentéte. NL_SJ, HASH_SJ, MERGE_SJ NL_AJ, HASH_AJ, MERGE_AJ A fentieket az alkérdésben lehet hintként megadni, és ekkor (ha lehetséges) az oracle a megfelelő algoritmussal fogja a semi-joint, illetve anti-joint elvégezni. CURSOR_SHARING_EXACT Arra utasítja az oracle-t, hogy semmiképpen ne cserélje le az utasítás elemzése közben a literálokat bind változóra. Amúgy ezt lehet, hogy megtenné mivel ezzel csökkenne az újraelemzések esélye. (lásd -> CURSOR_SHARING init paraméter) DRIVING_SITE(tabla) Elosztott lekérdezésnél van értelme. Arra utasítja az optimalizálót, hogy a megadott tábla adatbázisában hajtsa végre a műveletet. (pl. join esetén távoli táblák között) DYNAMIC_SAMPLING(tabla n) ahol 0 <= n <= 10 Menet közben próbál meg minta alapján döntéseket hozni a szelektivitásra vonatkozóan. Minél nagyobb az n értéke, annál nagyobb mintát használ. CACHE(tabla) Hatására a tábla blokkjai a buffer cache LRU listajanak "friss" végére kerülnek. Kis tábléknál hasznos, hogy sokáig lehessenek a buffer cache-ben. NOCACHE(tabla) Hatására a tábla blokkjai a buffer cache LRU listajanak "régi" végére kerülnek. Alapertelmezes szerint is ide kerülnének FULL TABLE SCAN esetén. APPEND INSERT utasításban az utolsó blokk utáni területre teszi be az adatokat, és nem a blokkokban meglévő szabad helyekre. Ezáltal gyorsabb lesz, de pazarlóbb. NOAPPEND A blokkok meglévő üres helyeit is kihasználja. (Illetve letiltja a párhuzamos insert-et) MERGE(V) V egy nézet neve. A nézet kiértékelésének egyik módja a nézet merge-elése a fő lekérdezésbe. Erre utasítja az optimalizálót. Inline nézet esetén a hintet beírhatjuk a nézet blokkjába (paraméter nélkül), vagy a fő lekérdezésbe (paraméterrel). NO_MERGE(V) Az előző ellentétére veszi rá az optimalizálót. NO_QUERY_TRANSFORMATION Az optimalizáló képes arra, hogy a lekérdezést valamilyen módon átalakítsa, és azt hajtsa végre. Ilyen átalakítás például az OR-expansion, View-merging, Subquery-unnest, Star-transformation, Materialized view-rewrite. A hint ezekről beszéli le az optimalizálót. A fenti átalakítások mindegyike külön-külön is kérhető illetve letiltható egy hinttel. USE_CONCAT - NO_EXPAND, MERGE - NO_MERGE, UNNEST - NO_UNNEST, STAR_TRANSFORMATION - NO_STAR_TRANSFORMATION, REWRITE - NO_REWRITE RULE Szabály alapú optimalizálást használ, de ez a hint már nem javasolt.