3

风景

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

4

1 回答 1

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

合并:

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

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

于 2013-12-13T15:13:18.007 回答