2016-05-31 11 views
0

Tabellendefinition zu verwenden:Kraft Oracle-Filterung in START MIT von außerhalb der Abfrage

create table Tree 
    (node varchar2(20), 
    parentNode varchar2(20), 
    val number); 

    create index idx_tree_01 on Tree 
    (node); 
    create index idx_tree_02 on Tree 
    (parentnode); 

Beispieldaten:

Insert into TREE (NODE,PARENTNODE,VAL) values ('2','1',2); 
Insert into TREE (NODE,PARENTNODE,VAL) values ('3','2',3); 
Insert into TREE (NODE,PARENTNODE,VAL) values ('4','2',3); 
Insert into TREE (NODE,PARENTNODE,VAL) values ('5','4',1); 
Insert into TREE (NODE,PARENTNODE,VAL) values ('6','3',1); 

anzeigen Definition:

create view tree_view as 
    select connect_by_root parentnode as firstNode, 
     lpad(' ', 2 * level - 2, ' ') || val as MyVal, 
     node, parentNode 
    from tree 
    start with parentnode in (select parentnode from tree) 
    connect by parentnode = prior node 

Jetzt will ich ausführen die Abfrage:

select * from tree_view 
where firstNode = '1' 

Der Ausführungsplan für die Abfrage ist:

------------------------------------------------------------------------- 
| Id | Operation        | Name  | E-Rows | 
------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT       |    |  | 
|* 1 | VIEW         | TREE_VIEW |  5 | 
|* 2 | CONNECT BY NO FILTERING WITH START-WITH|    |  | 
| 3 | TABLE ACCESS FULL      | TREE  |  5 | 
|* 4 | INDEX RANGE SCAN      | IDX_TREE_02 |  1 | 
------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

    1 - filter("FIRSTNODE"='1') 
    2 - access("PARENTNODE"=PRIOR NULL) 
     filter(IS NOT NULL) 
    4 - access("PARENTNODE"=:B1) 

Wie Sie die filterfirstnode = '1' am Ende verwendet wird, sehen. Ich möchte, dass es als das erste Ding verwendet wird.

I KANN NICHT die Ansicht ändern (ich kann nur vielleicht einige Hinweise hinzufügen).

Wie kann ich Oracle einen Hinweis geben, den Wert von firstNode in START WITH zu verwenden? Es würde eine große Leistungsverbesserung geben.

Meine echte "Baum" Tabelle ist ein paar Tabellen und Datenvolumen ist riesig. Wie bereits erwähnt, kann ich die Ansicht nicht ändern.

Sie schlagen mich nicht an:

  • Funktion mit firstnode Parameter und Pipeline- Ergebnis
  • Änderung Sichtsitzungskontext mit
  • Temptabelle Queering in Start in Start zu verwenden, mit
  • usw.

Die Ansicht muss gleich sein. Die Hinweise sind nur erlaubt.

+0

@PavelGatnar ich hier nicht fragen würde, wenn würde es eine solche Möglichkeit. Das Projekt ist live - die größeren Änderungen sind nicht erlaubt. – dcieslak

+0

Es ist nur Probe. In der Realität gibt es Ergebnisse von anderen Tabellen. Bitte beachte, dass meine Frage ist, wie man die Filterung von außerhalb der Abfrage auf START WITH verschiebt. – dcieslak

Antwort

0

first_node ist eine Spalte in der Ansicht, die von connect_by_root() Operator generiert wird. Die documentation says of this operator:

Sie können diesen Operator in der START WIT H Bedingung angeben oder die CONNECT BY Zustand.

So gibt es sowieso nicht zu erreichen, was Sie wollen. Wenn Sie darüber nachdenken, ist das nicht unangemessen: Um den ersten Knoten abzuleiten, muss die Abfrage die gesamte Hierarchie durchsuchen, um den Wurzelknoten für jedes Blatt zu finden.

Ein Tuning-Ansatz - obwohl wahrscheinlich nicht einer für Sie - ist es, die Hierarchie mittels transitiver Schließung zu materialisieren.Check out this other SO thread.

+0

Was ist mit rekursivem CTE? Denkst du, dass es dort möglich ist? 'Mit tv (firstNode, val, Knoten, parentNode, lvl) als ( wählen parentNode als firstNode, val, Knoten, parentNode, 0 als lvl von Baum Vereinigung alle wählen tv.firstNode, tr.val, tr .node, tr.parentNode, lvl + 1 von tv tree tr auf tv.node = tr.parentnode) wählen * von tv wo firstNode = '1'' – dcieslak

0

Sie versuchen PIPELINED Funktion erstellen, um Ansicht Reihen

CREATE TYPE t_row AS OBJECT (
    first_name VARCHAR2(1000), 
    my_val  VARCHAR2(1000) 
    ... 
); 

CREATE TYPE t_tab IS TABLE OF t_row; 

CREATE OR REPLACE FUNCTION get_hierarchy RETURN t_tab PIPELINED 
IS 
BEGIN 
    FOR rec IN (SELECT ...) LOOP 
     PIPE ROW (t_row(rec.firstNode, rec.myval, ...)); 
    END LOOP; 
RETURN; 
END get_hierarchy; 

zurückkehren und schreiben Abfrage

+0

Ich schrieb, dass es keine Lösung für mich in der Frage ist . Tut mir leid, dass du deine Zeit damit verschwendet hast, die Antwort zu schreiben. – dcieslak

+0

@dcieslak Aber Sie können unmodified Ansicht innerhalb der Funktion wählen, warum nicht? – hinotf

+0

Der Weg, wie es heißt, muss gleich bleiben. Ihre Lösung war zuerst, was ich dem Kunden vorgeschlagen habe, aber es wurde abgelehnt. Die nächste verwendete Anwendungskontext - die Ansicht bleibt - wurde aber auch abgelehnt. Ich denke APC hat Recht und es ist nicht möglich es zu tunen .. – dcieslak

Verwandte Themen