在视图中推送谓词

时间:2013-10-29 10:05:34

标签: sql performance oracle oracle10g

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谓词。

1 个答案:

答案 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 |
----------------------------------------------------------------------------------------------

因此,请尝试强制优化器使用与您合并查看并查看计划是否更改。