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。

 

 

 



 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章