powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Предикат "не пушится"
5 сообщений из 5, страница 1 из 1
Предикат "не пушится"
    #39620612
simplekindoflie
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подскажите, пожалуйста, почему изменив конструкцию с in (...) на join перестает работать view pushed predicate?

Тестовые данные:



Код: 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.
53.
54.
55.
56.
57.
58.
59.
60.
create table tmp_acc_dict
(
acc_id number(10) not null,
acc_name varchar2(255)
);

create table tmp_acc_xm
(
acc_id number(10) not null,
sd date not null,
ed date,
some_value varchar2(255)
);

create table tmp_acc_filter
(
acc_id number(10) not null,
filter_date date not null
);

insert all 
into tmp_acc_dict
values
(1,'acc1')
into tmp_acc_dict
values
(2,'acc2')
into tmp_acc_xm
values (1,sysdate-30, sysdate-2,'abs')
into tmp_acc_xm
values (1,sysdate, sysdate+10,'abs2')
into tmp_acc_xm
values (1,sysdate+11, null,'abs3')
into tmp_acc_xm
values (2,sysdate-30, null,'abs4')
into tmp_acc_filter
values (1,sysdate-10)
into tmp_acc_filter
values (1,trunc(sysdate,'dd')+5/24)
into tmp_acc_filter
values (2,sysdate-5)
select 1 from dual;

create unique index tmp_acc_dict_pk on tmp_acc_dict (acc_id);
create index tmp_acc_xm_fk on tmp_acc_xm (acc_id);
create index tmp_acc_xm_irs on tmp_acc_filter (filter_date);


create or replace view tmp_test_view as
select 
--+ push_pred(b) 
a.acc_id, a.acc_name, b.acc_xm_res from tmp_acc_dict a
             left join
                      (
                      select 
                      acc_id,  max(sd) acc_xm_res
                      from tmp_acc_xm xm
                      where sd>trunc(sysdate,'dd')
                      group by acc_id
                      ) b on a.acc_id=b.acc_id;




Запросы:



Код: 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.
53.
54.
select * from tmp_test_view a where acc_id in 
( select  acc_id from tmp_acc_filter b where filter_date>to_date(:1,'dd.mm.yyyy'))

----------------------------------------------------------------------------------------------
| Id   | Operation                        | Name            | Rows | Bytes | Cost | Time     |
----------------------------------------------------------------------------------------------
|    0 | SELECT STATEMENT                 |                 |    2 |   350 |    9 | 00:00:01 |
|    1 |   NESTED LOOPS OUTER             |                 |    2 |   350 |    9 | 00:00:01 |
|    2 |    MERGE JOIN SEMI               |                 |    2 |   328 |    5 | 00:00:01 |
|    3 |     TABLE ACCESS BY INDEX ROWID  | TMP_ACC_DICT    |    2 |   284 |    2 | 00:00:01 |
|    4 |      INDEX FULL SCAN             | TMP_ACC_DICT_PK |    2 |       |    1 | 00:00:01 |
|  * 5 |     SORT UNIQUE                  |                 |    3 |    66 |    3 | 00:00:01 |
|    6 |      TABLE ACCESS BY INDEX ROWID | TMP_ACC_FILTER  |    3 |    66 |    2 | 00:00:01 |
|  * 7 |       INDEX RANGE SCAN           | TMP_ACC_XM_IRS  |    3 |       |    1 | 00:00:01 |
|    8 |    VIEW PUSHED PREDICATE         |                 |    1 |    11 |    2 | 00:00:01 |
|    9 |     SORT GROUP BY                |                 |    1 |    22 |    2 | 00:00:01 |
| * 10 |      TABLE ACCESS BY INDEX ROWID | TMP_ACC_XM      |    1 |    22 |    2 | 00:00:01 |
| * 11 |       INDEX RANGE SCAN           | TMP_ACC_XM_FK   |    1 |       |    1 | 00:00:01 |
----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
------------------------------------------
* 5 - access("A"."ACC_ID"="ACC_ID")
* 5 - filter("A"."ACC_ID"="ACC_ID")
* 7 - access("FILTER_DATE">TO_DATE(:1,'dd.mm.yyyy'))
* 10 - filter("SD">TRUNC(SYSDATE@!,'fmdd'))
* 11 - access("ACC_ID"="A"."ACC_ID")



select * from tmp_test_view a 
join tmp_acc_filter b on (a.acc_id=b.acc_id and b.filter_date>to_date(:1,'dd.mm.yyyy'))

---------------------------------------------------------------------------------------------
| Id  | Operation                        | Name            | Rows | Bytes | Cost | Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |                 |    1 |   210 |    5 | 00:00:01 |
|   1 |   HASH GROUP BY                  |                 |    1 |   210 |    5 | 00:00:01 |
|   2 |    NESTED LOOPS OUTER            |                 |    1 |   210 |    4 | 00:00:01 |
|   3 |     NESTED LOOPS                 |                 |    1 |   188 |    3 | 00:00:01 |
|   4 |      TABLE ACCESS BY INDEX ROWID | TMP_ACC_FILTER  |    1 |    34 |    2 | 00:00:01 |
| * 5 |       INDEX RANGE SCAN           | TMP_ACC_XM_IRS  |    1 |       |    1 | 00:00:01 |
|   6 |      TABLE ACCESS BY INDEX ROWID | TMP_ACC_DICT    |    1 |   154 |    1 | 00:00:01 |
| * 7 |       INDEX UNIQUE SCAN          | TMP_ACC_DICT_PK |    1 |       |    0 | 00:00:01 |
| * 8 |     TABLE ACCESS BY INDEX ROWID  | TMP_ACC_XM      |    1 |    22 |    1 | 00:00:01 |
| * 9 |      INDEX RANGE SCAN            | TMP_ACC_XM_FK   |    2 |       |    0 | 00:00:01 |
---------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
------------------------------------------
* 5 - access("B"."FILTER_DATE">TO_DATE(:1,'dd.mm.yyyy'))
* 7 - access("A"."ACC_ID"="B"."ACC_ID")
* 8 - filter("SD"(+)>TRUNC(SYSDATE@!,'fmdd'))
* 9 - access("A"."ACC_ID"="ACC_ID"(+))




Заранее спасибо!
...
Рейтинг: 0 / 0
Предикат "не пушится"
    #39620649
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
simplekindoflieПодскажите, пожалуйста, почему изменив конструкцию с in (...) на join перестает работать view pushed predicate?

А куда ты собрался пропихивать предикат?
...
Рейтинг: 0 / 0
Предикат "не пушится"
    #39620683
XMLer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
simplekindoflie,
Очень даже пушится:
* 5 - access("B"."FILTER_DATE">TO_DATE(:1,'dd.mm.yyyy'))
...
Рейтинг: 0 / 0
Предикат "не пушится"
    #39620750
Андрей Панфилов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
simplekindoflie,

для начала в tmp_acc_filter нет PK, поэтому запросы с IN и JOIN получаются разные: IN строки не умножает, а JOIN умножает
...
Рейтинг: 0 / 0
Предикат "не пушится"
    #39622847
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
simplekindoflie,

Inline view b не существует после трансформаций запросов (в частности view merging) во втором случае.
Соотвественно хинт push_pred(b) более невалидный, ибо inline view b как таковой больше нет.

Инкапсулируя логику в представления и присыпая их хинтами крайне наивно пологать,
что хинты типа push_pred останутся валидными, при включении представления в другой запрос.
Не говоря уже про то, что конвертация ANSI синтаксиса в native может приводить созданию дополнительных inline view,
тоже делая хинты невалидными.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Предикат "не пушится"
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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