what is VW_NSO_1 view?

VW_NSO_1 我们查看执行计划的时候动态创建的,VM 是ORACLE视图的约定前缀/后缀,在和老外工作的时候,经常可以看到有VW的后缀,它就表示视图,这是习惯。

下面就是某日用品行业老大某某数据仓库的视图,它的后缀是VW

SQL> select view_name from dba_views where view_name like '%VW%';

VIEW_NAME
------------------------------------------------------------
GPOS_MDGC_TSC_ADL_VW
GPOS_MDGC_TSC_STORE_GRP_VW
GPOS_LLCA02_FACT_NT_SPEC_VW
GPOS_LLCA_ADL_VW
GPOS_LLCA_STORE_GRP_VW
GPOS_LLCA_AZ_FACT_VW
GPOS_RODE03_FACT_NATL_SPEC_VW

.....................................................................省略......................................................................

NSO 可以这样理解:nested subquery optimizing ,把in转换为JOIN,把NOT IN转换为 anti join(如果能确保列不为null)

那么什么时候oracle会生成 VW_NSO_1 这样的视图呢,请看下面的几个例子(基于ORACLE10g):

SQL> select count(*) from t1 where object_id not in (select  MAX(object_id) from t2 GROUP BY OWNER);

已用时间:  00: 00: 00.05

执行计划
----------------------------------------------------------
Plan hash value: 350791718

-----------------------------------------------------------------------------------
| Id  | Operation              | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |          |     1 |    18 |    32  (13)| 00:00:01 |
|   1 |  SORT AGGREGATE        |          |     1 |    18 |            |          |
|*  2 |   HASH JOIN RIGHT ANTI |          | 51176 |   899K|    32  (13)| 00:00:01 |
|   3 |    VIEW                | VW_NSO_1 |     1 |    13 |     3  (34)| 00:00:01 |
|   4 |     HASH GROUP BY      |          |     1 |    30 |     3  (34)| 00:00:01 |
|   5 |      TABLE ACCESS FULL | T2       |     1 |    30 |     2   (0)| 00:00:01 |
|   6 |    INDEX FAST FULL SCAN| T1_ID    | 51177 |   249K|    27   (4)| 00:00:01 |
-----------------------------------------------------------------------------------

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

   2 - access("OBJECT_ID"="$nso_col_1")

 

SQL> select count(*) from t1 where object_id not in (select  MAX(object_id) from t2 );

已用时间:  00: 00: 00.01

执行计划
----------------------------------------------------------
Plan hash value: 4201411252

--------------------------------------------------------------------------------------
| Id  | Operation                    | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |       |     1 |     5 |    29   (7)| 00:00:01 |
|   1 |  SORT AGGREGATE              |       |     1 |     5 |            |          |
|*  2 |   INDEX FAST FULL SCAN       | T1_ID | 51176 |   249K|    28   (8)| 00:00:01 |
|   3 |    SORT AGGREGATE            |       |     1 |    13 |            |          |
|   4 |     INDEX FULL SCAN (MIN/MAX)| T2_ID |     1 |    13 |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------

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

   2 - filter("OBJECT_ID"<> (SELECT MAX("OBJECT_ID") FROM "T2" "T2"))
SQL> select count(*) from t1 where object_id in (select  object_id from t2 where rownum=10);

已用时间:  00: 00: 00.00

执行计划
----------------------------------------------------------
Plan hash value: 3285035028

----------------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |     1 |    18 |     2  (50)| 00:00:01 |
|   1 |  SORT AGGREGATE       |          |     1 |    18 |            |          |
|   2 |   NESTED LOOPS        |          |     1 |    18 |     2  (50)| 00:00:01 |
|   3 |    VIEW               | VW_NSO_1 |     1 |    13 |     0   (0)| 00:00:01 |
|   4 |     HASH UNIQUE       |          |     1 |    13 |            |          |
|   5 |      COUNT            |          |       |       |            |          |
|*  6 |       FILTER          |          |       |       |            |          |
|   7 |        INDEX FULL SCAN| T2_ID    |     1 |    13 |     0   (0)| 00:00:01 |
|*  8 |    INDEX RANGE SCAN   | T1_ID    |     1 |     5 |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------

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

   6 - filter(ROWNUM=10)
   8 - access("OBJECT_ID"="$nso_col_1")

 

SQL> select count(*) from t1 where object_id in (select object_id from t2 where owner='SYS' UNION ALL select object_id from test where owner='SCOTT');

已用时间:  00: 00: 00.06

执行计划
----------------------------------------------------------
Plan hash value: 3457113806

-----------------------------------------------------------------------------------
| Id  | Operation              | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |          |     1 |    18 |    34   (9)| 00:00:01 |
|   1 |  SORT AGGREGATE        |          |     1 |    18 |            |          |
|*  2 |   HASH JOIN            |          |   140 |  2520 |    34   (9)| 00:00:01 |
|   3 |    VIEW                | VW_NSO_1 |   137 |  1781 |     5   (0)| 00:00:01 |
|   4 |     HASH UNIQUE        |          |   137 |  1526 |     5  (60)| 00:00:01 |
|   5 |      UNION-ALL         |          |       |       |            |          |
|*  6 |       TABLE ACCESS FULL| T2       |     1 |    30 |     2   (0)| 00:00:01 |
|*  7 |       INDEX RANGE SCAN | XXX      |   136 |  1496 |     3   (0)| 00:00:01 |
|   8 |    INDEX FAST FULL SCAN| T1_ID    | 51177 |   249K|    27   (4)| 00:00:01 |
-----------------------------------------------------------------------------------

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

   2 - access("OBJECT_ID"="$nso_col_1")
   6 - filter("OWNER"='SYS')
   7 - access("OWNER"='SCOTT')


SQL> select count(*) from t1 where object_id in (select object_id from t2 where owner='SYS' minus select object_id from test where owner='SCOTT');

已用时间:  00: 00: 00.03

执行计划
----------------------------------------------------------
Plan hash value: 182265946

-----------------------------------------------------------------------------------
| Id  | Operation              | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |          |     1 |    18 |     8  (25)| 00:00:01 |
|   1 |  SORT AGGREGATE        |          |     1 |    18 |            |          |
|   2 |   NESTED LOOPS         |          |     1 |    18 |     8  (25)| 00:00:01 |
|   3 |    VIEW                | VW_NSO_1 |     1 |    13 |     7  (29)| 00:00:01 |
|   4 |     MINUS              |          |       |       |            |          |
|   5 |      SORT UNIQUE       |          |     1 |    30 |            |          |
|*  6 |       TABLE ACCESS FULL| T2       |     1 |    30 |     2   (0)| 00:00:01 |
|   7 |      SORT UNIQUE       |          |   136 |  1496 |            |          |
|*  8 |       INDEX RANGE SCAN | XXX      |   136 |  1496 |     3   (0)| 00:00:01 |
|*  9 |    INDEX RANGE SCAN    | T1_ID    |     1 |     5 |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------

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

   6 - filter("OWNER"='SYS')
   8 - access("OWNER"='SCOTT')
   9 - access("OBJECT_ID"="$nso_col_1")

 

SQL> select count(*) from t1 where object_id in (SELECT LEVEL FROM DUAL CONNECT BY LEVEL<100);

已用时间:  00: 00: 00.05

执行计划
----------------------------------------------------------
Plan hash value: 1672622903

---------------------------------------------------------------------------------------------
| Id  | Operation                        | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |          |     1 |    18 |     4  (25)| 00:00:01 |
|   1 |  SORT AGGREGATE                  |          |     1 |    18 |            |          |
|   2 |   NESTED LOOPS                   |          |     1 |    18 |     4  (25)| 00:00:01 |
|   3 |    VIEW                          | VW_NSO_1 |     1 |    13 |     3  (34)| 00:00:01 |
|   4 |     HASH UNIQUE                  |          |     1 |       |     3  (34)| 00:00:01 |
|*  5 |      CONNECT BY WITHOUT FILTERING|          |       |       |            |          |
|   6 |       FAST DUAL                  |          |     1 |       |     2   (0)| 00:00:01 |
|*  7 |    INDEX RANGE SCAN              | T1_ID    |     1 |     5 |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------

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

   5 - filter(LEVEL<100)
   7 - access("OBJECT_ID"="$nso_col_1")



看到了吧,当子查询里面有 (max/min/avg,group by), rownum, UNION,UNION ALL,INTERSECT,MINUS,connect by ...start with ,

ORACLE会将子查询转换为视图VW_NSO_x,其实这些限制也是VIEW MERGE的限制,当一个视图中有上面的条件,ORACLE就无法对视图进行merge。

如果你不想CBO生成VW_NSO_1,你只需要在子查询里面加上hint NO_UNNEST 即可,这时候CBO就会走FILTER。

 

 

 



 

 

 

posted on 2012-03-15 16:20  如果蜗牛有爱情  阅读(193)  评论(0编辑  收藏  举报

导航