Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / условное "отключение" left join / 9 сообщений из 9, страница 1 из 1
15.11.2019, 16:08
    #39889785
--Eugene--
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
условное "отключение" left join
Вот, допусти, есть left join:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
with
x as (
select level a,
          mod(level,2) b
     from dual
     connect by level < 9
),
y as (
select level a
     from dual
     connect by level < 9
)
select x.a, x.b, y.a
     from x
          left join y
                on x.b != 0
                     and y.a = x.a

Вообще-то, когда я пишу условие x.b != 0 and y.a = x.a, тем самым я кагбы хочу сказать, что в случае когда x.b=0, я бы вообще не хотел чтобы происходил какой-либо доступ к Y.
Но, судя по плану, у оптимизатора другие мысли на этот счет:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
----------------------------------------------------------------------------------------
| Id  | Operation                      | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |      |      1 |    39 |     4   (0)| 00:00:01 |
|*  1 |  HASH JOIN OUTER               |      |      1 |    39 |     4   (0)| 00:00:01 |
|   2 |   VIEW                         |      |      1 |    26 |     2   (0)| 00:00:01 |
|*  3 |    CONNECT BY WITHOUT FILTERING|      |        |       |            |          |
|   4 |     FAST DUAL                  |      |      1 |       |     2   (0)| 00:00:01 |
|   5 |   VIEW                         |      |      1 |    13 |     2   (0)| 00:00:01 |
|*  6 |    CONNECT BY WITHOUT FILTERING|      |        |       |            |          |
|   7 |     FAST DUAL                  |      |      1 |       |     2   (0)| 00:00:01 |
----------------------------------------------------------------------------------------

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

   1 - access("Y"."A"(+)="X"."A")
       filter("X"."B"<>CASE  WHEN ("Y"."A"(+) IS NOT NULL) THEN 0 ELSE 0 END )
   3 - filter(LEVEL<9)
   6 - filter(LEVEL<9)

Как добиться того, чтобы доступ к "приджоенным" таблицам не осуществлялся вовсе в зависимости от условия, на основе данных из таблиц, уже "просмотренных" (ну, если допустим LEFT JOIN-ов несколько) ?
...
Рейтинг: 0 / 0
15.11.2019, 16:41
    #39889817
j2k
j2k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
условное "отключение" left join
--Eugene--, т.е. что-то вроде этого:
Код: plsql
1.
left join y  on case when x.b = 0 then null else y.a end = x.a 


?
...
Рейтинг: 0 / 0
15.11.2019, 16:42
    #39889819
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
условное "отключение" left join
Код: plsql
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.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
explain plan for
with
x as (
select level a,
          mod(level,2) b
     from dual
     connect by level < 9
),
y as (
select level a
     from dual
     connect by level < 9
)
select x.a, x.b, y.a
     from x
          left join y
                on 1 = case
                         when x.b != 0 then 1
                         when  y.a = x.a then 1
                       end
/
SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------
Plan hash value: 3580413835

---------------------------------------------------------------------------------------
| Id  | Operation                      | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |      |     1 |    39 |     4   (0)| 00:00:01 |
|   1 |  NESTED LOOPS OUTER            |      |     1 |    39 |     4   (0)| 00:00:01 |
|   2 |   VIEW                         |      |     1 |    26 |     2   (0)| 00:00:01 |
|*  3 |    CONNECT BY WITHOUT FILTERING|      |       |       |            |          |
|   4 |     FAST DUAL                  |      |     1 |       |     2   (0)| 00:00:01 |
|*  5 |   VIEW                         |      |     1 |    13 |     2   (0)| 00:00:01 |
|*  6 |    CONNECT BY WITHOUT FILTERING|      |       |       |            |          |
|   7 |     FAST DUAL                  |      |     1 |       |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------------------

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

   3 - filter(LEVEL<9)
   5 - filter(CASE  WHEN "X"."B"<>0 THEN 1 WHEN "Y"."A"(+)="X"."A" THEN 1 END
              =1)
   6 - filter(LEVEL<9)

22 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
15.11.2019, 16:45
    #39889823
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
условное "отключение" left join
--Eugene--,

не совсем понял что надо
но мож вместо on x.b != 0 достаточно where x.b != 0

......
stax
...
Рейтинг: 0 / 0
15.11.2019, 16:51
    #39889830
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
условное "отключение" left join
SY,

36 rows selected.

так задумано?

.....
stax
...
Рейтинг: 0 / 0
15.11.2019, 17:08
    #39889849
--Eugene--
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
условное "отключение" left join
SY
Код: plsql
1.
2.
3.
4.
                on 1 = case
                         when x.b != 0 then 1
                         when  y.a = x.a then 1
                       end

в данном (простейшем) случае, может быть, но если таблицы X и Y не маленькие, а колонка Y.a индексирована и хотелось бы иметь возможность задействовать этот индекс? ведь в случае с предикатом 1 = CASE так не получится
...
Рейтинг: 0 / 0
15.11.2019, 17:12
    #39889852
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
условное "отключение" left join
Stax

так задумано?


Упс:

Код: plsql
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.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
explain plan for
with
x as (
select level a,
          mod(level,2) b
     from dual
     connect by level < 9
),
y as (
select level a
     from dual
     connect by level < 9
)
select x.a, x.b, y.a
     from x
          left join y
                on 1 = case
                         when x.b != 0 then case
                                              when  y.a = x.a then 1
                                            end
                       end
/
SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------
Plan hash value: 3580413835

---------------------------------------------------------------------------------------
| Id  | Operation                      | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |      |     1 |    39 |     4   (0)| 00:00:01 |
|   1 |  NESTED LOOPS OUTER            |      |     1 |    39 |     4   (0)| 00:00:01 |
|   2 |   VIEW                         |      |     1 |    26 |     2   (0)| 00:00:01 |
|*  3 |    CONNECT BY WITHOUT FILTERING|      |       |       |            |          |
|   4 |     FAST DUAL                  |      |     1 |       |     2   (0)| 00:00:01 |
|*  5 |   VIEW                         |      |     1 |    13 |     2   (0)| 00:00:01 |
|*  6 |    CONNECT BY WITHOUT FILTERING|      |       |       |            |          |
|   7 |     FAST DUAL                  |      |     1 |       |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------------------

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

   3 - filter(LEVEL<9)
   5 - filter(CASE  WHEN "X"."B"<>0 THEN CASE "Y"."A"(+) WHEN "X"."A" THEN 1
              END  END =1)
   6 - filter(LEVEL<9)

22 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
15.11.2019, 17:23
    #39889865
--Eugene--
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
условное "отключение" left join
Stax
мож вместо on x.b != 0 достаточно where x.b != 0
не достаточно, поскольку в общем случае это нужно для следующего:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
select *
	from t0
		left join t1
			on t1.id = t0.id
		left join t2
			on t1.a = 'INCLUDE-T2'
				and t2.id = t0.id
		left join t3
			on t1.a = 'INCLUDE-T2'
				and t2.a = 'INCLUDE-T3'
				and t3.id = t0.id
...
Рейтинг: 0 / 0
15.11.2019, 20:30
    #39889930
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
условное "отключение" left join
Да просто вместо хэш джойна форсируйте нестед лупс...
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / условное "отключение" left join / 9 сообщений из 9, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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