powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / 9i: Сортировка ветвей через индекс
12 сообщений из 12, страница 1 из 1
9i: Сортировка ветвей через индекс
    #32099006
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот на 8i и ранее есть способ отсортировать ветви в иерархической выборке через построение соответствующего индекса:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
drop table test
/
create table test (
    test_id number( 9 )
  , parent_id number( 9 )
  , name varchar2( 64 )
  , constraint pk_test primary key (test_id)
  , constraint fk_test_self foreign key (parent_id)
      references test (test_id)
)
/
insert into test (test_id, parent_id, name) values ( 1 , null, 'Root1');
insert into test (test_id, parent_id, name) values ( 10 ,  1 , '10');
insert into test (test_id, parent_id, name) values ( 12 ,  1 , '12');
insert into test (test_id, parent_id, name) values ( 11 ,  1 , '11');

create index ix_test_parent_name on test (parent_id, name);


На 9i это почему-то не катит. Т.е. индеск используется, но сортировки не происходит:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
dan@oraspb>; select  --+ index(test ix_test_parent_name)
 
   2          *
   3   from test
   4   connect by prior test_id = parent_id
   5   start with parent_id is null
   6   /

   TEST_ID  PARENT_ID NAME
 ---------- ---------- ------------------------------
 
          1             Root1
         10            1   10 
         12            1   12 
         11            1   11 


Execution Plan
 ----------------------------------------------------------
 
    0       SELECT STATEMENT Optimizer=FIRST_ROWS (Cost= 1  Card= 1  Bytes= 6 
           0 )

    1      0    CONNECT BY (WITH FILTERING)
    2      1      NESTED LOOPS
    3      2        TABLE ACCESS (FULL) OF 'TEST' (Cost= 2  Card= 3  Bytes= 39 )
    4      2        TABLE ACCESS (BY USER ROWID) OF 'TEST'
    5      1      NESTED LOOPS
    6      5        BUFFER (SORT)
    7      6          CONNECT BY PUMP
    8      5        TABLE ACCESS (BY INDEX ROWID) OF 'TEST' (Cost= 1  Card= 1 
           Bytes= 60 )

    9      8          INDEX (RANGE SCAN) OF 'IX_TEST_PARENT_NAME' (NON-UNI
          QUE) (Cost= 2  Card= 1 )


Т.е. только order siblings by остается?
...
Рейтинг: 0 / 0
9i: Сортировка ветвей через индекс
    #32099017
ShgGena
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Убери hint по индексу и/или FIRST_ROW и посмотри как план изменится.
В 9 специальнай шаг плана выполнения предусмотрен для иерархичеких запросов.
Посему скорее всего только - siblings by и сотается.
...
Рейтинг: 0 / 0
9i: Сортировка ветвей через индекс
    #32099025
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Странно, не меняется план, ни с FIRST_ROW, ни с RULE, ни вообще без хинта. А как он на 8-ке выглядит?
...
Рейтинг: 0 / 0
9i: Сортировка ветвей через индекс
    #32099040
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В 8i
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
TEST_ID    PARENT_ID  NAME                                                            
 ---------- ---------- ----------------------------------------------------------------
 
          1             Root1                                                           
         10            1   10                                                               
         11            1   11                                                               
         12            1   12                                                               
Выбрано  4  строк.

Execution Plan
 ----------------------------------------------------------
 
    0       SELECT STATEMENT Optimizer=RULE (Cost= 1  Card= 20  Bytes= 1200 )
    1      0    CONNECT BY
    2      1      TABLE ACCESS (FULL) OF 'TEST' (Cost= 1  Card= 100  Bytes= 130 
           0 )

    3      1      TABLE ACCESS (BY USER ROWID) OF 'TEST'
    4      1      TABLE ACCESS (BY INDEX ROWID) OF 'TEST' (Cost= 1  Card= 20 
          Bytes= 1200 )

    5      4        INDEX (RANGE SCAN) OF 'IX_TEST_PARENT_NAME' (NON-UNIQU
          E) (Cost= 2  Card= 20 )


Но я только одного не понимаю, почему ты решил что должно быть упорядочивание? Обычный hint index() - ничего не гарантирует. Попробуй index_asc
...
Рейтинг: 0 / 0
9i: Сортировка ветвей через индекс
    #32099047
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот desc(убывание)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
SQLWKS> select  --+ index_desc(test ix_test_parent_name) 
 
      2 > * 
      3 >  from work.test 
      4 >  connect by prior test_id = parent_id 
      5 >  start with parent_id is null 
      6 >  
      7 > 
      8 > 
TEST_ID    PARENT_ID  NAME                                                            
 ---------- ---------- ----------------------------------------------------------------
 
          1             Root1                                                           
         12            1   12                                                               
         11            1   11                                                               
         10            1   10                                                               
Выбрано  4  строк.



Вот asc(возрастание)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
SQLWKS> select  --+ index_asc(test ix_test_parent_name) 
 
      2 > * 
      3 >  from work.test 
      4 >  connect by prior test_id = parent_id 
      5 >  start with parent_id is null 
      6 >  
      7 > 
      8 > 
TEST_ID    PARENT_ID  NAME                                                            
 ---------- ---------- ----------------------------------------------------------------
 
          1             Root1                                                           
         10            1   10                                                               
         11            1   11                                                               
         12            1   12                                                               
Выбрано  4  строк.
...
Рейтинг: 0 / 0
9i: Сортировка ветвей через индекс
    #32099058
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну или через order by гарантировано:
Код: plaintext
1.
2.
3.
4.
5.
6.
select 
* 
 from work.test 
 connect by prior test_id = parent_id 
 start with parent_id is null 
order by  1  ;


А индексы подхватятся при RULE в любом случае ибо RULE
...
Рейтинг: 0 / 0
9i: Сортировка ветвей через индекс
    #32099064
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Стоит признать, хоть в 9-ке и индексы подхватываются, но таким образом сортировка не производится:( А order by всю иерархию порушит. Стоит учесть при мигрировании.
...
Рейтинг: 0 / 0
9i: Сортировка ветвей через индекс
    #32099233
Mergen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что будет если несколько корней, и их тоже нужно отсортировать? В 8-ке(i)
...
Рейтинг: 0 / 0
9i: Сортировка ветвей через индекс
    #32099289
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В таком случае, Александр Сычев подсказал, следует у корней значение поля parent_id сделать не null (иначе запись не войдет в индекс), а какое-то значимое. 0, к примеру, и запрос переписать как start wih parent_id = 0. Конечно, возникает проблема с внешним ключем parent_id на первичный ключ таблицы, но можно подумать, что важнее, ссылочная целостность или сортировка. К сожалению, не могу проверить, 8i под рукой нет.
...
Рейтинг: 0 / 0
9i: Сортировка ветвей через индекс
    #32099365
Mergen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
спасибо за совет :)
...
Рейтинг: 0 / 0
9i: Сортировка ветвей через индекс
    #32099776
ShgGena
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
О плане выполнения в 9i -->
Запрос правда не совсем обычный, но на других такая же картина:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
select lpad('.',(level- 1 )* 2 ,'.') || to_char(a.node_id) node,
       cast(multiset(select node_id from train.a_tree c
                     where a.node_id <> c.node_id
                     connect by prior c.root_id=c.node_id
                     start with c.node_id=a.node_id ) as nodes) nodes
from train.a_tree a
connect by prior a.node_id=a.root_id
start with a.node_id= 6 ;

Execution Plan
 ----------------------------------------------------------
 
    0       SELECT STATEMENT Optimizer=CHOOSE (Cost= 2  Card= 14  Bytes= 98 )
    1      0    CONNECT BY (WITH FILTERING)
    2      1      NESTED LOOPS
    3      2        INDEX (UNIQUE SCAN) OF 'PK_A_TREE' (UNIQUE) (Cost= 1  Card= 1  Bytes= 4 )
    4      2        TABLE ACCESS (BY USER ROWID) OF 'A_TREE'
    5      1      NESTED LOOPS
    6      5        BUFFER (SORT)
    7      6          CONNECT BY PUMP
    8      5        TABLE ACCESS (BY INDEX ROWID) OF 'A_TREE' (Cost= 2  Card = 14  Bytes= 98 )
    9      8          INDEX (RANGE SCAN) OF 'I_A_ROOT' (NON-UNIQUE) (Cost=  1  Card= 14 )
...
Рейтинг: 0 / 0
9i: Сортировка ветвей через индекс
    #32099868
ShgGena
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Analogichiy zapros v 8i privodit k sovsem drugomu planu:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SQL> select lpad('.',(level- 1 )* 2 ,'.') || to_char(a.node_id) node,
       cast(multiset(select node_id from train.a_tree c
                     connect by prior c.node_id=c.root_id
                     start with c.node_id=a.node_id ) as child_node) r
from train.a_tree a
connect by prior a.node_id=a.root_id
start with a.root_id= 0 ;

Execution Plan
 ----------------------------------------------------------
 
    0 	  SELECT STATEMENT Optimizer=CHOOSE (Cost= 1  Card= 3  Bytes= 12 )
    1 	 0    CONNECT BY
    2 	 1      INDEX (RANGE SCAN) OF 'I_A_ROOT' (NON-UNIQUE) (Cost= 1  Card= 3  Bytes= 6 )
    3 	 1      TABLE ACCESS (BY USER ROWID) OF 'A_TREE'
    4 	 1      TABLE ACCESS (FULL) OF 'A_TREE' (Cost= 1  Card= 3  Bytes= 12 )


Pri etom vnuternniy podzapros --> cast(multiset(select ....)) voobsche v plane ne pokazivaetsya.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / 9i: Сортировка ветвей через индекс
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]