Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / заменить left join на connect by / 5 сообщений из 5, страница 1 из 1
31.10.2016, 19:30
    #39338265
mama.said
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
заменить left join на connect by
добрый день,

есть такой запрос
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
with dt as (
  select 1 as id, null as prnt_id, 'A' as code from dual union all
  select 2 as id, null as prnt_id, 'B' as code from dual union all
  select 3 as id, 2    as prnt_id, 'C' as code from dual union all
  select 4 as id, null as prnt_id, 'D' as code from dual 
)
select * from dt t
left join (
  select v.prnt_id, max(v.code), max(v.id) 
  from dt v 
  group by v.prnt_id
 ) vw on vw.prnt_id = t.id


из плана видно что мы 2 раза фулсканим одну и ту же таблицу
Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
--------------------------------------------------------------------------------------------------------
| Id  | Operation                  | Name                      | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |                           |     4 |    72 |    14  (58)| 00:00:01 |
|   1 |  TEMP TABLE TRANSFORMATION |                           |       |       |            |          |
|   2 |   LOAD AS SELECT           | SYS_TEMP_0FD9D6625_3EC012 |       |       |            |          |
|   3 |    UNION-ALL               |                           |       |       |            |          |
|   4 |     FAST DUAL              |                           |     1 |       |     2   (0)| 00:00:01 |
|   5 |     FAST DUAL              |                           |     1 |       |     2   (0)| 00:00:01 |
|   6 |     FAST DUAL              |                           |     1 |       |     2   (0)| 00:00:01 |
|   7 |     FAST DUAL              |                           |     1 |       |     2   (0)| 00:00:01 |
|*  8 |   HASH JOIN OUTER          |                           |     4 |    72 |     6  (34)| 00:00:01 |
|   9 |    VIEW                    |                           |     4 |    36 |     2   (0)| 00:00:01 |
|  10 |     TABLE ACCESS FULL      | SYS_TEMP_0FD9D6625_3EC012 |     4 |   116 |     2   (0)| 00:00:01 |
|  11 |    VIEW                    |                           |     1 |     9 |     3  (34)| 00:00:01 |
|  12 |     HASH GROUP BY          |                           |     1 |     9 |     3  (34)| 00:00:01 |
|  13 |      VIEW                  |                           |     4 |    36 |     2   (0)| 00:00:01 |
|  14 |       TABLE ACCESS FULL    | SYS_TEMP_0FD9D6625_3EC012 |     4 |   116 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------------


можно ли запрос как то переписать например с помощью connect by получив такой же результат но с одним проходом по таблице
ID PRNT_ID CODE PRNT_ID MAX(V.CODE) MAX(V.ID)2 B 2 C 34 D 3 2 C 1 A

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
with dt as (
  select 1 as id, null as prnt_id, 'A' as code from dual union all
  select 2 as id, null as prnt_id, 'B' as code from dual union all
  select 3 as id, 2    as prnt_id, 'C' as code from dual union all
  select 4 as id, null as prnt_id, 'D' as code from dual 
)
select t.* 
from dt t
start with t.prnt_id is null
connect by prior t.id = t.prnt_id 

...
Рейтинг: 0 / 0
31.10.2016, 19:53
    #39338272
dbms_photoshop
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
заменить left join на connect by
mama.saidможно ли запрос как то переписать например с помощью connect by получив такой же результат но с одним проходом по таблицеЕсли тебе кажется, что в случае connect by выполняется один проход - то по факту может быть один full scan c запихиванием всего набора в память и потом полного его чтения на каждом уровне построения иерархии.
Чудес не бывает. Фулл скан будет один, но проходов столько, сколько уровней.

Если есть навязчивая цель один проход, то 9923928
Но это решение во-первых порождает сортировку, во-вторых могут быть дополнительные проблема с производительностью аналитики на нестандартных окнах, в-третьих сопровождающих такой код может совершенно не обрадовать.
...
Рейтинг: 0 / 0
31.10.2016, 19:59
    #39338274
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
заменить left join на connect by
mama.said,

Недостаточно описана магия данных.
1. max(v.code) и max(v.id) - значения могут принадлежать разным строкам, иначе незачем писать группировку. Это вызывает подозрения на некорректный результат.
2. Напрашивается вопрос об одноуровневости, где верхний всегда prnt_id = null. Тогда есть альтернативы.
3. Почему бы не использовать индекс на prnt_id. Второй заход по индексу бывает эффективнее сортировки всего набора.
...
Рейтинг: 0 / 0
31.10.2016, 20:21
    #39338286
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
заменить left join на connect by
Кури aналитические функциии.

SY.
...
Рейтинг: 0 / 0
31.10.2016, 20:23
    #39338287
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
заменить left join на connect by
А с какого перепугу тут outer?

SY.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / заменить left join на connect by / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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