the scenerio
explain plan for
select l.etl_id , v.*
from v_load_base v, etl_log l
where l.is_active = 1
and v.ddate between trunc(l.load_from_date) and l.load_to_date
and v.starttime_full between l.load_from_date and l.load_to_date;
制定此执行计划
--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 444 | | 31624 (4)| 00:06:20 |
| 1 | SORT ORDER BY | | 3 | 444 | | 31624 (4)| 00:06:20 |
|* 2 | HASH JOIN | | 3 | 444 | | 31623 (4)| 00:06:20 |
| 3 | NESTED LOOPS OUTER | | 3 | 378 | | 31413 (4)| 00:06:17 |
|* 4 | HASH JOIN | | 3 | 348 | | 31410 (4)| 00:06:17 |
|* 5 | HASH JOIN | | 1252 | 118K| 2144K| 23428 (4)| 00:04:42 |
|* 6 | HASH JOIN | | 27786 | 1818K| | 764 (7)| 00:00:10 |
| 7 | NESTED LOOPS | | 8 | 264 | | 7 (0)| 00:00:01 |
|* 8 | TABLE ACCESS FULL | ETL_LOG | 1 | 21 | | 3 (0)| 00:00:01 |
|* 9 | TABLE ACCESS FULL | MD | 8 | 96 | | 4 (0)| 00:00:01 |
| 10 | TABLE ACCESS FULL | DS | 479K| 15M| | 748 (6)| 00:00:09 |
| 11 | TABLE ACCESS FULL | MDS | 7280K| 208M| | 7823 (5)| 00:01:34 |
| 12 | TABLE ACCESS FULL | TASKS | 7760K| 140M| | 7844 (5)| 00:01:35 |
| 13 | TABLE ACCESS BY INDEX ROWID| ETL_GIS | 1 | 10 | | 1 (0)| 00:00:01 |
|* 14 | INDEX UNIQUE SCAN | ETL_GIS_UK | 1 | | | 0 (0)| 00:00:01 |
| 15 | TABLE ACCESS FULL | DETAILS_TABLE | 292K| 6280K| | 204 (8)| 00:00:03 |
--------------------------------------------------------------------------------------------------------
表etl_log
的连接谓词被下推到视图v_load_base
(第8行)。
我基于与上面相同的查询创建了一个名为v_load_base_active
的视图。
查询新视图会产生以下计划
explain plan for select * from v_load_base_active;
----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 861 | | 63583 (8)| 00:12:43 |
| 1 | NESTED LOOPS | | 3 | 861 | | 63583 (8)| 00:12:43 |
|* 2 | TABLE ACCESS FULL | ETL_LOG | 1 | 21 | | 3 (0)| 00:00:01 |
|* 3 | VIEW | V_LOAD_BASE | 3 | 798 | | 63580 (8)| 00:12:43 |
| 4 | SORT ORDER BY | | 422K| 51M| 110M| 63580 (8)| 00:12:43 |
|* 5 | HASH JOIN RIGHT OUTER | | 422K| 51M| | 51513 (9)| 00:10:19 |
| 6 | TABLE ACCESS FULL | ETL_GIS | 5958 | 59580 | | 17 (0)| 00:00:01 |
|* 7 | HASH JOIN | | 422K| 47M| 9712K| 51488 (9)| 00:10:18 |
| 8 | TABLE ACCESS FULL | LINES_DETAILS | 292K| 6280K| | 204 (8)| 00:00:03 |
|* 9 | HASH JOIN | | 422K| 38M| 35M| 48647 (10)| 00:09:44 |
|* 10 | HASH JOIN | | 422K| 30M| | 27365 (14)| 00:05:29 |
| 11 | TABLE ACCESS FULL | MD | 3103 | 37236 | | 4 (0)| 00:00:01 |
|* 12 | HASH JOIN | | 7301K| 445M| 21M| 24366 (3)| 00:04:53 |
| 13 | TABLE ACCESS FULL| DS | 479K| 15M| | 748 (6)| 00:00:09 |
| 14 | TABLE ACCESS FULL| MSD | 7280K| 208M| | 7823 (5)| 00:01:34 |
| 15 | TABLE ACCESS FULL | TASKS | 7760K| 140M| | 7844 (5)| 00:01:35 |
----------------------------------------------------------------------------------------------------
谓词未被推送。这导致性能大幅下降。
我已尝试在视图/*+ PUSH_PRED(v) */
中明确设置提示,但计划不会更改。
如何让优化器在视图中推送谓词......?
v_load_base
不包含分析函数。第一个查询证明可以推送谓词 。修改
请注意,oracle没有在执行计划中声明谓词是用VIEW PUSHED PREDICATE
推送的。但是,看一下计划,很明显oracle将视图的sql转换为包含etl_log
谓词。
答案 0 :(得分:2)
我怀疑它是否在第一种情况下推动谓词,因为它将在计划中。更可能的是合并由MERGE / NO_MERGE提示控制。见下面的例子。
使用NO_MERGE:
SQL> explain plan for
2 select /*+NO_MERGE(so)*/ *
3 from siebel.s_org_ext soe,
4 (select sx.attrib_08, s.*
5 from siebel.s_opty s
6 inner join siebel.s_opty_x sx on s.row_id = sx.row_id) so
7 where soe.row_id = so.pr_dept_ou_id
8 and soe.row_id like '1-8ZT%'
9 and so.db_last_upd between soe.db_last_upd and soe.db_last_upd - 365;
Explained
SQL> select * from table(dbms_xplan.display);
Plan hash value: 1802470607
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13258 | 55 (2)| 00:00:01 |
|* 1 | HASH JOIN | | 1 | 13258 | 55 (2)| 00:00:01 |
| 2 | TABLE ACCESS BY INDEX ROWID| S_ORG_EXT | 1 | 1047 | 3 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | S_ORG_EXT_P1 | 1 | | 2 (0)| 00:00:01 |
| 4 | VIEW | | 1084 | 12M| 52 (2)| 00:00:01 |
|* 5 | HASH JOIN | | 1084 | 528K| 52 (2)| 00:00:01 |
| 6 | TABLE ACCESS FULL | S_OPTY_X | 1573 | 15730 | 17 (0)| 00:00:01 |
|* 7 | TABLE ACCESS FULL | S_OPTY | 1084 | 517K| 34 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
使用MERGE:
SQL> explain plan for
2 select /*+MERGE(so)*/*
3 from siebel.s_org_ext soe,
4 (select sx.attrib_08, s.*
5 from siebel.s_opty s
6 inner join siebel.s_opty_x sx on s.row_id = sx.row_id) so
7 where soe.row_id = so.pr_dept_ou_id
8 and soe.row_id like '1-8ZT%'
9 and so.db_last_upd between soe.db_last_upd and soe.db_last_upd - 365;
Explained
SQL> select * from table(dbms_xplan.display);
Plan hash value: 4111959163
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1546 | 6 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 1 | 1546 | 6 (0)| 00:00:01 |
| 2 | NESTED LOOPS | | 1 | 1536 | 5 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID| S_ORG_EXT | 1 | 1047 | 3 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | S_ORG_EXT_P1 | 1 | | 2 (0)| 00:00:01 |
|* 5 | TABLE ACCESS BY INDEX ROWID| S_OPTY | 1 | 489 | 2 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | S_OPTY_M64_X | 1 | | 1 (0)| 00:00:01 |
| 7 | TABLE ACCESS BY INDEX ROWID | S_OPTY_X | 1 | 10 | 1 (0)| 00:00:01 |
|* 8 | INDEX UNIQUE SCAN | S_OPTY_X_P1 | 1 | | 0 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
因此,请尝试强制优化器使用与您合并查看并查看计划是否更改。