Hirdetés

Új hozzászólás Aktív témák

  • bpx
    őstag

    PL/SQL Developer 9.x-ről álltunk át a napokban 12-es verzióra. Valószínűleg ez lehet a probléma forrása (talán az üzemeltetés nem hangolta tökéletesre az adatbázis szervert?).

    Plant nem tudok mutatni, a lekérdezés egyébként kb. így néz ki:

    SELECT t1.mezo_1
    ,t1.mezo_2
    FROM (SELECT t.id
    ,t.mezo_1
    ,t.mezo_2
    FROM tabla_1 t
    WHERE feltetel_1
    AND feltetel_2
    ...
    AND feltetel_n) t1
    ,(SELECT t.id
    FROM tabla_2 t
    WHERE feltetel_1
    AND feltetel_2
    ...
    AND feltetel_n) t2
    WHERE t1.id = t2.id

    Ez futott korábban 1 másodpercig, most meg 5-10 perc között. t1 és t2 allekérdezés is 200-300 eredménysort ad vissza (mindkettő dimenziótábla), külön-külön 1 másodpercen belül most is lefutnak. Mindkét táblában az id egyedi, szám formátumú.

    Az a vicces, hogyha t1 allekérdezésben találomra kikommentezek egy szűrőfeltételt (az eredménysorok száma 10-15%-kal nő), akkor az egész lekérdezés ismét 1 másodpercen belül fut.

    Legalapabb hintekkel próbálkoztam (use_hash, use_nl stb.), de igazából nem tudom, mikor mit kell használni. Tapasztalatból csak annyi van meg, hogy nagyméretű ténytáblák kötésénél 90%-ban csökkenti a futási időt a use_hash hint.

    Tudom, hogy ez még mindig kevés, és hogy jobban kellene specifikálni a problémát, de a hét végére valószínűleg kapok segítséget munkatársaktól, tehát mindenképp meg fog oldódni a probléma, csak azt hittem, vannak általánosan alkalmazható hintelések.

    Ha most tényleg az a cél, hogy a 2 subqueryt egymástól független megcsinálja 1-1 alkalommal, akkor kb. így:

    SELECT /*+ use_hash(t1 t2) */ t1.mezo_1
    ,t1.mezo_2
    FROM (SELECT /*+ no_merge no_push_pred */ t.id
    ,t.mezo_1
    ,t.mezo_2
    FROM tabla_1 t
    WHERE feltetel_1
    AND feltetel_2
    ...
    AND feltetel_n) t1
    ,(SELECT /*+ no_merge no_push_pred */ t.id
    FROM tabla_2 t
    WHERE feltetel_1
    AND feltetel_2
    ...
    AND feltetel_n) t2
    WHERE t1.id = t2.id;

    A subquery itt úgy viselkedik mintha view lenne. A view-kat az adatbázis "kifejti" ha tudja, az eredeti példát szerintem simán átírja az adatbázis úgy, mintha nem is lennének subquery-k, csak a 2 táblára a join. Ez a view merging, ezt akadályozza meg a no_merge hint.

    Ha a view-kon kívül is vannak egyéb feltételek, azt az adatbázis be tudja helyezni a view-n belülre. Pl. a "select * from view1 where column1='...'" lekérdezést végre lehet úgy hajtani, hogy előállítja a view1 teljes eredményhalmazát, majd a végén alkalmazza a column1 szűrést, de úgy is, hogy a column1 szűrést átírja úgy, mintha a view-n belül lenne. Ez nem csak egyszerű szűrésekre működik, hanem joinra is, tehát miután előállította a t1 tartalmát, az adatbázis a t2-be már beviszi a tabla_2.id = t1.id szűrést és felhasználja a t1-ből jövő id értékeket, ez a join predicate pushdown. Ezeket tiltja a no_push_pred.

    A use_hash-t meg csak a biztonság kedvéért tettem oda, hogy mindkettő subquery-t csak 1-szer csinálja meg, és ne válasszon nested loops-t.

    Aztán ezen kívül még lehetnek mindenféle más optimalizálások, amelyekre most nem gondoltam és további hintek kellenének.

    De persze nem ezt tartom a jó megoldásnak.

Új hozzászólás Aktív témák