Oracle AUSFÜHREN, SOFORTIGE änderungen erklären, plan der Abfrage

Ich habe eine gespeicherte Prozedur, ich bin Aufruf mit EXECUTE IMMEDIATE. Das Problem, das ich bin vor ist, dass die explain-plan ist anders, wenn ich den Aufruf der Prozedur direkt vs, wenn ich EXECUTE IMMEDIATE Aufruf der Prozedur. Dadurch verursacht wird, dass die Ausführungszeit zu erhöhen 5x. Der wesentliche Unterschied zwischen den Plänen ist, dass wenn ich execute immediate der optimizer ist nicht unnesting die Unterabfrage (habe ich mit Hilfe einer not EXISTS-Bedingung). Wir sind mit Rule Based Optimizer hier bei der Arbeit für die meisten Abfragen, aber dafür hat man einen Hinweis auf die Verwendung eines index, so das CBO verwendet wird (allerdings, wir sammeln keine Statistiken für Tabellen). Wir laufen Oracle9i Enterprise Edition Release 9.2.0.4.0 - 64bit-Produktion.

Beispiel:
Schnell:

begin
   package.procedure;
end;
/

Langsam:

begin
   execute immediate 'begin package.' || proc_name || '; end;';
end;
/

Abfrage:

  SELECT                                               /*+ INDEX(A IDX_A_1) */
        a.store_cd,
           b.itm_cd itm_cd,
           CEIL ( (new_date - a.dt) / 7) week_num,
           SUM (a.qty * b.demand_weighting * b.CONVERT) qty
    FROM            a
                 INNER JOIN
                    b
                 ON (a.itm_cd = b.old_itm_cd)
              INNER JOIN
                 (SELECT   g.store_grp_cd, g.store_cd
                    FROM   g, h
                   WHERE   g.store_grp_cd = h.fdo_cd AND h.fdo_type = '1') d
              ON (a.store_cd = d.store_cd AND b.store_grp_cd = d.store_grp_cd)
           CROSS JOIN
              dow
   WHERE       a.dt BETWEEN dow.new_date - 91 AND dow.new_date - 1
           AND a.sls_wr_cd = 'W'
           AND b.demand_type = 'S'
           AND b.old_itm_cd IS NOT NULL
           AND NOT EXISTS
                 (SELECT
                        NULL
                    FROM   f
                   WHERE   f.store_grp_cd = a.store_cd
                           AND b.old_itm_cd = f.old_itm_cd)
GROUP BY   a.store_cd, b.itm_cd, CEIL ( (dow.new_date - a.dt) / 7)

Gut Erklären, Plan:

OPERATION OPTIONS OBJECT_NAME OBJECT_TYPE ID PARENT_ID 
SELECT-ANWEISUNG 0 
SORTIEREN GRUPPE VON 1 0 
NESTED LOOPS-2 1 
HASH JOIN ANTI 3 2 
TABLE ACCESS BY INDEX ROWID H 4 3 
NESTED LOOPS 5 4 
NESTED LOOPS 6 5 
NESTED LOOPS 7 6 
TABLE ACCESS FULL B 8 7 
TABLE ACCESS BY INDEX ROWID 9 7 
INDEX-RANGE-SCAN IDX_A_1 EINZIGARTIGE 10 9 
INDEX UNIQUE SCAN G UNIQUE 11 6 
INDEX-RANGE-SCAN H_UK EINZIGARTIGEN 12 5 
TABLE ACCESS FULL F 13 3 
TABLE ACCESS FULL DOW 14 2 

Schlecht Erklären, Plan:

OPERATION OPTIONS OBJECT_NAME OBJECT_TYPE ID PARENT_ID 
SELECT-ANWEISUNG 0 
SORTIEREN GRUPPE VON 1 0 
NESTED LOOPS-2 1 
NESTED LOOPS 3 2 
GESCHACHTELTE SCHLEIFEN 4 3 
NESTED LOOPS 5 4 
TABLE ACCESS FULL B 6 5 
TABLE ACCESS BY INDEX ROWID 7 5 
INDEX-RANGE-SCAN IDX_A_1 EINZIGARTIGE 8 7 
TABLE ACCESS FULL F 9 8 
INDEX UNIQUE SCAN G EINZIGARTIGE 10 4 
TABLE ACCESS BY INDEX ROWID H 11 3 
INDEX-RANGE-SCAN H_UK EINZIGARTIGEN 12 11 
TABLE ACCESS FULL DOW 13 2 

In das schlecht erklären, planen die Unterabfrage nicht unnested. Ich war in der Lage zu reproduzieren, die schlecht planen, indem ein no_unnest Hinweis auf die Unterabfrage; allerdings konnte ich nicht reproduzieren guten plan mithilfe der unnest-Hinweis (beim ausführen der Prozedur mit execute immediate). Andere Hinweise werden vom Optimierer berücksichtigt bei der Verwendung der execute immediate-nur nicht die unnest-Hinweis.

Dieses Problem tritt nur auf, wenn ich mit execute immediate Aufruf der Prozedur. Wenn ich execute immediate auf die Abfrage selbst verwendet es den guten plan.

  • ich würde denken, die Regel-basierte oprimizer sollte konsistent sein. vielleicht noch ein Hinweis und sehen, ob das auch änderungen der plan - um zu überprüfen, dass die RBO ist eigentlich in Kraft...
  • Wir haben einen Hinweis auf die Verwendung eines index in der Abfrage schon so macht, dass die Ursache der CBO verwendet werden, statt für die Abfrage? Auch so, ich versucht, indem die unnest-Hinweis auf die Unterabfrage, aber es scheint nicht zu Ehren den Hinweis.
  • Ein index-Hinweis nicht dazu, dass die CBO verwendet werden. Sie können die FIRST_ROWS oder ALL_ROWS Hinweise zu erzwingen CBO-Nutzung, oder die REGEL Hinweis zu zwingen, RBO-Nutzung. Vielleicht sollten Sie post von der eigentlichen SQL-Abfrage und die zwei verschiedenen Pläne, die Sie sehen, für Sie.
  • Poste bitte die tatsächlichen Abfragen und die Pläne generiert-und dann können wir vielleicht Anregungen bieten. Eine Sache: wenn man keine stats auf Ihre Tabellen meine Erfahrung ist, dass die CBO wird mit ziemlicher Sicherheit geben, die Sie für ein mieser plan. Welche version von Oracle sind Sie?
  • Ich habe die Abfrage und die beiden erklären, Pläne zu meinem post.
InformationsquelleAutor Gunny | 2010-05-07
Schreibe einen Kommentar