2016-05-31 3 views
0
определения

таблицы:Force Oracle использовать фильтрацию в START WITH извне запроса

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); 

Образец данных:

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); 

Посмотреть определение:

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 

Теперь я хочу, чтобы выполнить запрос:

select * from tree_view 
where firstNode = '1' 

План выполнения запроса является:

------------------------------------------------------------------------- 
| 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) 

Как вы можете видеть, что filterfirstnode = '1' используется в конце. Я хочу, чтобы это использовалось как первое.

I НЕ МОЖЕТ изменить вид (могу добавить только некоторые подсказки).

Как я могу дать указание Oracle использовать значение firstNode в START WITH? Это обеспечит отличное улучшение производительности.

My real "tree" table - это пара таблиц и объем данных огромен. Как я уже говорил, я не могу изменить представление.

Не предлагать мне:

  • функции с параметром firstnode и конвейерными результате
  • изменения зрения использования контекста сеанса в начале с
  • временной таблицей queering в начале с
  • и т.д.

Вид должен быть таким же. Подсказки разрешены.

+0

@PavelGatnar Я бы не спросить здесь, когда будет такая возможность. Проект вживую - большие изменения не допускаются. – dcieslak

+0

Это просто образец. В реальности есть результат из какой-то другой таблицы. Обратите внимание, что мой вопрос заключается в том, как перенести фильтрацию в START WITH из-за запроса. – dcieslak

ответ

0

first_node - столбец в представлении, который генерируется оператором connect_by_root(). documentation says of this operator:

Вы не можете указать этот оператор в состоянии START WIT H или состояние CONNECT BY.

Таким образом, вы все равно не достигли желаемого. Если вы думаете об этом, это не является необоснованным: для получения первого узла запрос должен пройти всю иерархию, чтобы найти корневой узел для каждого листа.

Один подход к настройке, хотя, вероятно, не один открытый для вас, - это материализация иерархии с использованием транзитивного закрытия.Проверьте this other SO thread.

+0

А как насчет рекурсивных КТР? Как вы думаете, это возможно? 'С телевизором (firstNode, вал, узел, ParentNode, ур) как ( выберите ParentNode как firstNode, вал, узел, ParentNode, 0, как ур из дерева объединение всех выберите tv.firstNode, tr.val, тр .node, tr.parentNode, lvl + 1 из tv join tree tr на tv.node = tr.parentnode) выберите * from tv где firstNode = '1'' – dcieslak

0

Вы можете попробовать создать конвейерную функцию, чтобы вернуться просматривать строки

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; 

и переписывание запросов

+0

Я написал, что это не решение для меня в вопросе , Извините, вы потратили свое время, написав ответ. – dcieslak

+0

@dcieslak Но вы можете использовать немодифицированный вид внутри функции, почему бы и нет? – hinotf

+0

Способ, которым он призван, должен оставаться неизменным. Ваше решение было первым, что я предложил клиенту, но оно было отклонено. В следующем контексте использовался контекст приложения - вид остается - но он тоже был отклонен. Я предполагаю, что APC прав, и это невозможно настроить. – dcieslak

 Смежные вопросы

  • Нет связанных вопросов^_^