[20140823]12c join convert连接转换.txt

[20140823]12c join convert连接转换.txt

--前面提高12c执行计划的Partial Join Evaluation.现在看看12c join convert.
--链接:

1.建立测试环境:

SCOTT@test01p> @ver
BANNER                                                                               CON_ID
-------------------------------------------------------------------------------- ----------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production              0

create table t1 as select rownum id ,cast('testtest' as varchar2(10)) name from dual connect by levelcreate table t2 as select rownum id ,cast('testtest' as varchar2(10)) name from dual connect by levelcreate unique index pk_t1 on t1 (id);
alter table t1 add constraint pk_t1 primary key (id);
create unique index pk_t2 on t2 (id);
alter table t2 add constraint pk_t2 primary key (id);
execute dbms_stats.gather_table_stats(user,'t1',cascade=>true,method_opt=>'for all columns size 1',no_invalidate=>false);
execute dbms_stats.gather_table_stats(user,'t2',cascade=>true,method_opt=>'for all columns size 1',no_invalidate=>false);

SYS@test01p> @hide _convert_set_to_join
NAME                  DESCRIPTION                                 DEFAULT_VALUE  SESSION_VALUE  SYSTEM_VALUE
--------------------- ------------------------------------------- -------------- -------------- ------------
_convert_set_to_join  enables conversion of set operator to join  TRUE           FALSE          FALSE
--12.1.0.1版本_convert_set_to_join=false.

2.测试:
SCOTT@test01p> alter session set statistics_level=all;
Session altered.
SCOTT@test01p> select * from t1 intersect select * from t2;
ID NAME
--- ---------
  1 testtest
  2 testtest
  3 testtest
  4 testtest
  5 testtest
  6 testtest
  7 testtest
  8 testtest
  9 testtest
10 testtest
10 rows selected.

SCOTT@test01p> @dpc '' outline
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  g5jv20wwdh1zz, child number 0
-------------------------------------
select * from t1 intersect select * from t2
Plan hash value: 1917753433
------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |      1 |        |   576 (100)|     10 |00:00:00.08 |     269 |       |       |          |
|   1 |  INTERSECTION       |      |      1 |        |            |     10 |00:00:00.08 |     269 |       |       |          |
|   2 |   SORT UNIQUE       |      |      1 |    100K|   573   (1)|    100K|00:00:00.07 |     266 |  5510K|   963K| 4897K (0)|
|   3 |    TABLE ACCESS FULL| T1   |      1 |    100K|    77   (0)|    100K|00:00:00.01 |     266 |       |       |          |
|   4 |   SORT UNIQUE       |      |      1 |     10 |     3   (0)|     10 |00:00:00.01 |       3 |  2048 |  2048 | 2048  (0)|
|   5 |    TABLE ACCESS FULL| T2   |      1 |     10 |     3   (0)|     10 |00:00:00.01 |       3 |       |       |          |
------------------------------------------------------------------------------------------------------------------------------
Outline Data
-------------
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('12.1.0.1')
      DB_VERSION('12.1.0.1')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      OUTLINE_LEAF(@"SEL$2")
      OUTLINE_LEAF(@"SET$1")
      FULL(@"SEL$2" "T2"@"SEL$2")
      FULL(@"SEL$1" "T1"@"SEL$1")
      END_OUTLINE_DATA
  */

--可以发现执行出现INTERSECTION,与一些11g版本一样.Buffers=269.

SCOTT@test01p> select /*+ SET_TO_JOIN(@"SET$1") */ * from t1 intersect select * from t2;
ID NAME
-- --------------------
7 testtest
8 testtest
2 testtest
5 testtest
1 testtest
3 testtest
6 testtest
10 testtest
4 testtest
9 testtest

--注意输出的顺序发生了一些"混乱",对比前面的输出.

SCOTT@test01p> @dpc '' outline
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  7y6uhq1r2bhnr, child number 0
-------------------------------------
select /*+ SET_TO_JOIN(@"SET$1") */ * from t1 intersect select * from t2
Plan hash value: 847386728
-----------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                     | Name  | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |       |      1 |        |    13 (100)|     10 |00:00:00.01 |      13 |       |       |          |
|   1 |  HASH UNIQUE                  |       |      1 |     10 |    13   (0)|     10 |00:00:00.01 |      13 |  1600K|  1600K|  979K (0)|
|   2 |   NESTED LOOPS                |       |      1 |        |            |     10 |00:00:00.01 |      13 |       |       |          |
|   3 |    NESTED LOOPS               |       |      1 |     10 |    13   (0)|     10 |00:00:00.01 |      12 |       |       |          |
|   4 |     TABLE ACCESS FULL         | T2    |      1 |     10 |     3   (0)|     10 |00:00:00.01 |       3 |       |       |          |
|*  5 |     INDEX UNIQUE SCAN         | PK_T1 |     10 |      1 |     0   (0)|     10 |00:00:00.01 |       9 |       |       |          |
|*  6 |    TABLE ACCESS BY INDEX ROWID| T1    |     10 |      1 |     1   (0)|     10 |00:00:00.01 |       1 |       |       |          |
-----------------------------------------------------------------------------------------------------------------------------------------
Outline Data
-------------
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('12.1.0.1')
      DB_VERSION('12.1.0.1')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$02B15F54")
      MERGE(@"SEL$1")
      MERGE(@"SEL$2")
      OUTLINE(@"SET$09AAA538")
      SET_TO_JOIN(@"SET$1")
      ~~~~~~~~~~~~~~~~~~~~~
      OUTLINE(@"SEL$1")
      OUTLINE(@"SEL$2")
      OUTLINE(@"SET$1")
      FULL(@"SEL$02B15F54" "T2"@"SEL$2")
      INDEX(@"SEL$02B15F54" "T1"@"SEL$1" ("T1"."ID"))
      LEADING(@"SEL$02B15F54" "T2"@"SEL$2" "T1"@"SEL$1")
      USE_NL(@"SEL$02B15F54" "T1"@"SEL$1")
      NLJ_BATCHING(@"SEL$02B15F54" "T1"@"SEL$1")
      USE_HASH_AGGREGATION(@"SEL$02B15F54")
      END_OUTLINE_DATA
  */
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("T1"."ID"="T2"."ID")
   6 - filter(SYS_OP_MAP_NONNULL("T1"."NAME")=SYS_OP_MAP_NONNULL("T2"."NAME"))
Note
-----
   - this is an adaptive plan

--可以发现几点变化:
1.执行计划没有出现INTERSECTION,而是转化为join操作.
2.另外一个副作用这个执行计划adaptive plan,后面再看看为什么?
3.buffer=13,比原来大大减少.操作先扫描T2小表.在连接T1,逻辑读自然大大减少.
4.看不明白,为什么输出的顺序会发生变化.....?????也许出在执行计划的HASH UNIQUE上.

3.使用提示看看:
SCOTT@test01p> select /*+ OPT_PARAM('_convert_set_to_join' 'true') */ * from t1 intersect select * from t2;
ID NAME
-- --------------------
7 testtest
8 testtest
2 testtest
5 testtest
1 testtest
3 testtest
6 testtest
10 testtest
4 testtest
9 testtest
10 rows selected.
--执行计划与select /*+ SET_TO_JOIN(@"SET$1") */ * from t1 intersect select * from t2一样,不再贴出.

4.修改参数测试:
--我使用的12.1.0.1.0版本._convert_set_to_join=false.设置为true看看.
SCOTT@test01p> alter session set "_convert_set_to_join"=true ;
Session altered.

SCOTT@test01p> select * from t1 intersect select * from t2;
ID NAME
-- --------------------
7 testtest
8 testtest
2 testtest
5 testtest
1 testtest
3 testtest
6 testtest
10 testtest
4 testtest
9 testtest
10 rows selected.

--执行计划与select /*+ SET_TO_JOIN(@"SET$1") */ * from t1 intersect select * from t2一样,不在贴出.

5.看看是否顺序可以改变:
SCOTT@test01p> select * from V$SQL_HINT where name like '%USE%AGGREGATION%';
NAME                    SQL_FEATURE          CLASS                 INVERSE                  TARGET_LEVEL   PROPERTY VERSION    VERSION_OUTLINE CON_ID
----------------------- -------------------- --------------------- ------------------------ ------------ ---------- ---------- --------------- ------
USE_HASH_AGGREGATION    QKSFM_ALL            USE_HASH_AGGREGATION  NO_USE_HASH_AGGREGATION             2          0 10.2.0.1   10.2.0.5             0
NO_USE_HASH_AGGREGATION QKSFM_ALL            USE_HASH_AGGREGATION  USE_HASH_AGGREGATION                2          0 10.2.0.1   10.2.0.5             0
--猜测换成NO_USE_HASH_AGGREGATION看看.

select
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('12.1.0.1')
      DB_VERSION('12.1.0.1')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$02B15F54")
      MERGE(@"SEL$1")
      MERGE(@"SEL$2")
      OUTLINE(@"SET$09AAA538")
      SET_TO_JOIN(@"SET$1")
      OUTLINE(@"SEL$1")
      OUTLINE(@"SEL$2")
      OUTLINE(@"SET$1")
      FULL(@"SEL$02B15F54" "T2"@"SEL$2")
      INDEX(@"SEL$02B15F54" "T1"@"SEL$1" ("T1"."ID"))
      LEADING(@"SEL$02B15F54" "T2"@"SEL$2" "T1"@"SEL$1")
      USE_NL(@"SEL$02B15F54" "T1"@"SEL$1")
      NLJ_BATCHING(@"SEL$02B15F54" "T1"@"SEL$1")
      NO_USE_HASH_AGGREGATION(@"SEL$02B15F54")
      END_OUTLINE_DATA
  */ * from t1 intersect select * from t2;

ID NAME
-- --------------------
1 testtest
2 testtest
3 testtest
4 testtest
5 testtest
6 testtest
7 testtest
8 testtest
9 testtest
10 testtest
10 rows selected.

SCOTT@test01p> @dpc '' outline
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  3frmt98v3kjsp, child number 0
-------------------------------------
select   /*+       BEGIN_OUTLINE_DATA       IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('12.1.0.1')
DB_VERSION('12.1.0.1')       ALL_ROWS
OUTLINE_LEAF(@"SEL$02B15F54")       MERGE(@"SEL$1")
MERGE(@"SEL$2")       OUTLINE(@"SET$09AAA538")
SET_TO_JOIN(@"SET$1")       OUTLINE(@"SEL$1")       OUTLINE(@"SEL$2")
    OUTLINE(@"SET$1")       FULL(@"SEL$02B15F54" "T2"@"SEL$2")
INDEX(@"SEL$02B15F54" "T1"@"SEL$1" ("T1"."ID"))
LEADING(@"SEL$02B15F54" "T2"@"SEL$2" "T1"@"SEL$1")
USE_NL(@"SEL$02B15F54" "T1"@"SEL$1")       NLJ_BATCHING(@"SEL$02B15F54"
"T1"@"SEL$1")       NO_USE_HASH_AGGREGATION(@"SEL$02B15F54")
END_OUTLINE_DATA   */ * from t1 intersect select * from t2

Plan hash value: 1438968633

-----------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                     | Name  | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |       |      1 |        |    13 (100)|     10 |00:00:00.01 |      13 |       |       |          |
|   1 |  SORT UNIQUE                  |       |      1 |      8 |    13   (0)|     10 |00:00:00.01 |      13 |  2048 |  2048 | 2048  (0)|
|   2 |   NESTED LOOPS                |       |      1 |        |            |     10 |00:00:00.01 |      13 |       |       |          |
|   3 |    NESTED LOOPS               |       |      1 |     10 |    13   (0)|     10 |00:00:00.01 |      12 |       |       |          |
|   4 |     TABLE ACCESS FULL         | T2    |      1 |     10 |     3   (0)|     10 |00:00:00.01 |       3 |       |       |          |
|*  5 |     INDEX UNIQUE SCAN         | PK_T1 |     10 |      1 |     0   (0)|     10 |00:00:00.01 |       9 |       |       |          |
|*  6 |    TABLE ACCESS BY INDEX ROWID| T1    |     10 |      1 |     1   (0)|     10 |00:00:00.01 |       1 |       |       |          |
-----------------------------------------------------------------------------------------------------------------------------------------
Outline Data
-------------
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('12.1.0.1')
      DB_VERSION('12.1.0.1')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$02B15F54")
      MERGE(@"SEL$1")
      MERGE(@"SEL$2")
      OUTLINE(@"SET$09AAA538")
      SET_TO_JOIN(@"SET$1")
      OUTLINE(@"SEL$1")
      OUTLINE(@"SEL$2")
      OUTLINE(@"SET$1")
      FULL(@"SEL$02B15F54" "T2"@"SEL$2")
      INDEX(@"SEL$02B15F54" "T1"@"SEL$1" ("T1"."ID"))
      LEADING(@"SEL$02B15F54" "T2"@"SEL$2" "T1"@"SEL$1")
      USE_NL(@"SEL$02B15F54" "T1"@"SEL$1")
      NLJ_BATCHING(@"SEL$02B15F54" "T1"@"SEL$1")
      END_OUTLINE_DATA
  */
Predicate Information (identified by operation id):
---------------------------------------------------
   5 - access("T1"."ID"="T2"."ID")
   6 - filter(SYS_OP_MAP_NONNULL("T1"."NAME")=SYS_OP_MAP_NONNULL("T2"."NAME"))
60 rows selected.

6.最后观察为什么出现adaptive plan.

--重新进入:
SCOTT@test01p> alter session set statistics_level=all;
Session altered.

select /*+ SET_TO_JOIN(@"SET$1") */ * from t1 intersect select * from t2;

SCOTT@test01p> @dpc '' outline,adaptive
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  7y6uhq1r2bhnr, child number 2
-------------------------------------
select /*+ SET_TO_JOIN(@"SET$1") */ * from t1 intersect select * from t2

Plan hash value: 847386728

--------------------------------------------------------------------------------------------------------------------------------------------
|   Id  | Operation                      | Name  | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------------------------------
|     0 | SELECT STATEMENT               |       |      1 |        |    13 (100)|     10 |00:00:00.01 |      13 |       |       |          |
|     1 |  HASH UNIQUE                   |       |      1 |      1 |    13   (0)|     10 |00:00:00.01 |      13 |  1600K|  1600K|  985K (0)|
|- *  2 |   HASH JOIN                    |       |      1 |      1 |    13   (0)|     10 |00:00:00.01 |      13 |  1079K|  1079K|          |
|     3 |    NESTED LOOPS                |       |      1 |        |            |     10 |00:00:00.01 |      13 |       |       |          |
|     4 |     NESTED LOOPS               |       |      1 |      1 |    13   (0)|     10 |00:00:00.01 |      12 |       |       |          |
|-    5 |      STATISTICS COLLECTOR      |       |      1 |        |            |     10 |00:00:00.01 |       3 |       |       |          |
|     6 |       TABLE ACCESS FULL        | T2    |      1 |     10 |     3   (0)|     10 |00:00:00.01 |       3 |       |       |          |
|  *  7 |      INDEX UNIQUE SCAN         | PK_T1 |     10 |      1 |     0   (0)|     10 |00:00:00.01 |       9 |       |       |          |
|  *  8 |     TABLE ACCESS BY INDEX ROWID| T1    |     10 |      1 |     1   (0)|     10 |00:00:00.01 |       1 |       |       |          |
|-    9 |    TABLE ACCESS FULL           | T1    |      0 |      1 |     1   (0)|      0 |00:00:00.01 |       0 |       |       |          |
--------------------------------------------------------------------------------------------------------------------------------------------
Outline Data
-------------
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('12.1.0.1')
      DB_VERSION('12.1.0.1')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$02B15F54")
      MERGE(@"SEL$1")
      MERGE(@"SEL$2")
      OUTLINE(@"SET$09AAA538")
      SET_TO_JOIN(@"SET$1")
      OUTLINE(@"SEL$1")
      OUTLINE(@"SEL$2")
      OUTLINE(@"SET$1")
      FULL(@"SEL$02B15F54" "T2"@"SEL$2")
      INDEX(@"SEL$02B15F54" "T1"@"SEL$1" ("T1"."ID"))
      LEADING(@"SEL$02B15F54" "T2"@"SEL$2" "T1"@"SEL$1")
      USE_NL(@"SEL$02B15F54" "T1"@"SEL$1")
      NLJ_BATCHING(@"SEL$02B15F54" "T1"@"SEL$1")
      USE_HASH_AGGREGATION(@"SEL$02B15F54")
      END_OUTLINE_DATA
  */
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("T1"."ID"="T2"."ID" AND SYS_OP_MAP_NONNULL("T1"."NAME")=SYS_OP_MAP_NONNULL("T2"."NAME"))
   7 - access("T1"."ID"="T2"."ID")
Note
-----
   - statistics feedback used for this statement
   - this is an adaptive plan (rows marked '-' are inactive)
59 rows selected.
--对adaptive plan不是很熟悉,可以理解marked '-' are inactive.或者先生成的是这些带-,实际执行时发生了改变.

7.再回头看看原始的执行计划:
SCOTT@test01p> @dpc '' outline
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  g5jv20wwdh1zz, child number 0
-------------------------------------
select * from t1 intersect select * from t2
Plan hash value: 1917753433
------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |      1 |        |   576 (100)|     10 |00:00:00.08 |     269 |       |       |          |
|   1 |  INTERSECTION       |      |      1 |        |            |     10 |00:00:00.08 |     269 |       |       |          |
|   2 |   SORT UNIQUE       |      |      1 |    100K|   573   (1)|    100K|00:00:00.07 |     266 |  5510K|   963K| 4897K (0)|
|   3 |    TABLE ACCESS FULL| T1   |      1 |    100K|    77   (0)|    100K|00:00:00.01 |     266 |       |       |          |
|   4 |   SORT UNIQUE       |      |      1 |     10 |     3   (0)|     10 |00:00:00.01 |       3 |  2048 |  2048 | 2048  (0)|
|   5 |    TABLE ACCESS FULL| T2   |      1 |     10 |     3   (0)|     10 |00:00:00.01 |       3 |       |       |          |
------------------------------------------------------------------------------------------------------------------------------

--即使我们建立每个表上都建立了主键(字段id),而老的方法选择的仍然是全表扫描,每条记录肯定唯一,而在选择sort unique有点多余.
--即使写成如下:
select id from t1 intersect select id from t2;
--执行计划如下,依旧出现SORT UNIQUE.buffers=218 , 也不小.
-------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation              | Name  | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |       |      1 |        |   365 (100)|     10 |00:00:00.10 |     218 |      2 |       |       |          |
|   1 |  INTERSECTION          |       |      1 |        |            |     10 |00:00:00.10 |     218 |      2 |       |       |          |
|   2 |   SORT UNIQUE          |       |      1 |    100K|   364   (1)|    100K|00:00:00.09 |     216 |      1 |  4588K|   893K| 4078K (0)|
|   3 |    INDEX FAST FULL SCAN| PK_T1 |      1 |    100K|    58   (0)|    100K|00:00:00.04 |     216 |      1 |       |       |          |
|   4 |   SORT UNIQUE NOSORT   |       |      1 |     10 |     1   (0)|     10 |00:00:00.01 |       2 |      1 |       |       |          |
|   5 |    INDEX FULL SCAN     | PK_T2 |      1 |     10 |     1   (0)|     10 |00:00:00.01 |       2 |      1 |       |       |          |
-------------------------------------------------------------------------------------------------------------------------------------------

--实际上写成这样,输出结果一样.

select id,name from t2 where (id,name) in ( select id,name from t1);
select id,name from t1 where (id,name) in ( select id,name from t2);

--仅仅贴出第二个执行计划.实际上如果看Plan hash value是一样的.
SCOTT@test01p> select id,name from t1 where (id,name) in ( select id,name from t2);
        ID NAME
---------- --------------------
         1 testtest
         2 testtest
         3 testtest
         4 testtest
         5 testtest
         6 testtest
         7 testtest
         8 testtest
         9 testtest
        10 testtest
10 rows selected.

SCOTT@test01p> @dpc '' outline,adaptive
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  dnk2d8zxsk4gf, child number 0
-------------------------------------
select id,name from t1 where (id,name) in ( select id,name from t2)
Plan hash value: 4001747048
----------------------------------------------------------------------------------------------------------------
|   Id  | Operation                     | Name  | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers |
----------------------------------------------------------------------------------------------------------------
|     0 | SELECT STATEMENT              |       |      1 |        |    13 (100)|     10 |00:00:00.01 |      23 |
|- *  1 |  HASH JOIN                    |       |      1 |     10 |    13   (0)|     10 |00:00:00.01 |      23 |
|     2 |   NESTED LOOPS                |       |      1 |        |            |     10 |00:00:00.01 |      23 |
|     3 |    NESTED LOOPS               |       |      1 |     10 |    13   (0)|     10 |00:00:00.01 |      13 |
|-    4 |     STATISTICS COLLECTOR      |       |      1 |        |            |     10 |00:00:00.01 |       4 |
|     5 |      TABLE ACCESS FULL        | T2    |      1 |     10 |     3   (0)|     10 |00:00:00.01 |       4 |
|  *  6 |     INDEX UNIQUE SCAN         | PK_T1 |     10 |      1 |     0   (0)|     10 |00:00:00.01 |       9 |
|  *  7 |    TABLE ACCESS BY INDEX ROWID| T1    |     10 |      1 |     1   (0)|     10 |00:00:00.01 |      10 |
|-    8 |   TABLE ACCESS FULL           | T1    |      0 |      1 |     1   (0)|      0 |00:00:00.01 |       0 |
----------------------------------------------------------------------------------------------------------------
Outline Data
-------------
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('12.1.0.1')
      DB_VERSION('12.1.0.1')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$5DA710D3")
      UNNEST(@"SEL$2")
      OUTLINE(@"SEL$1")
      OUTLINE(@"SEL$2")
      FULL(@"SEL$5DA710D3" "T2"@"SEL$2")
      INDEX(@"SEL$5DA710D3" "T1"@"SEL$1" ("T1"."ID"))
      LEADING(@"SEL$5DA710D3" "T2"@"SEL$2" "T1"@"SEL$1")
      USE_NL(@"SEL$5DA710D3" "T1"@"SEL$1")
      NLJ_BATCHING(@"SEL$5DA710D3" "T1"@"SEL$1")
      END_OUTLINE_DATA
  */
Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("ID"="ID" AND "NAME"="NAME")
   6 - access("ID"="ID")
   7 - filter("NAME"="NAME")
Note
-----
   - this is an adaptive plan (rows marked '-' are inactive)
52 rows selected.

8.换成exists看看.

select id,name from t2 where exists ( select null from t1 where t1.id=t2.id and t1.name =t2.name);
select id,name from t1 where exists ( select null from t2 where t2.id=t1.id and t2.name =t1.name);

SCOTT@test01p> @dpc '' outline,adaptive
PLAN_TABLE_OUTPUT
--------------------------------------
SQL_ID  by9m9cvtgybq8, child number 0
-------------------------------------
select id,name from t1 where exists ( select null from t2 where t2.id=t1.id and t2.name =t1.name)
Plan hash value: 1238133714
-------------------------------------------------------------------------------------------------------------------------------------------
|   Id  | Operation                     | Name  | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------------------------
|     0 | SELECT STATEMENT              |       |      1 |        |     8 (100)|     10 |00:00:00.01 |      22 |       |       |          |
|- *  1 |  HASH JOIN                    |       |      1 |     10 |     8   (0)|     10 |00:00:00.01 |      22 |  1096K|  1096K|          |
|     2 |   NESTED LOOPS                |       |      1 |        |            |     10 |00:00:00.01 |      22 |       |       |          |
|     3 |    NESTED LOOPS               |       |      1 |     10 |     8   (0)|     10 |00:00:00.01 |      12 |       |       |          |
|-    4 |     STATISTICS COLLECTOR      |       |      1 |        |            |     10 |00:00:00.01 |       3 |       |       |          |
|     5 |      SORT UNIQUE              |       |      1 |     10 |     3   (0)|     10 |00:00:00.01 |       3 |  2048 |  2048 | 2048  (0)|
|     6 |       TABLE ACCESS FULL       | T2    |      1 |     10 |     3   (0)|     10 |00:00:00.01 |       3 |       |       |          |
|  *  7 |     INDEX UNIQUE SCAN         | PK_T1 |     10 |      1 |     0   (0)|     10 |00:00:00.01 |       9 |       |       |          |
|  *  8 |    TABLE ACCESS BY INDEX ROWID| T1    |     10 |      1 |     1   (0)|     10 |00:00:00.01 |      10 |       |       |          |
|-    9 |   TABLE ACCESS FULL           | T1    |      0 |      1 |     1   (0)|      0 |00:00:00.01 |       0 |       |       |          |
-------------------------------------------------------------------------------------------------------------------------------------------
Outline Data
-------------
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('12.1.0.1')
      DB_VERSION('12.1.0.1')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$5DA710D3")
      UNNEST(@"SEL$2")
      OUTLINE(@"SEL$1")
      OUTLINE(@"SEL$2")
      FULL(@"SEL$5DA710D3" "T2"@"SEL$2")
      INDEX(@"SEL$5DA710D3" "T1"@"SEL$1" ("T1"."ID"))
      LEADING(@"SEL$5DA710D3" "T2"@"SEL$2" "T1"@"SEL$1")
      USE_NL(@"SEL$5DA710D3" "T1"@"SEL$1")
      NLJ_BATCHING(@"SEL$5DA710D3" "T1"@"SEL$1")
      SEMI_TO_INNER(@"SEL$5DA710D3" "T2"@"SEL$2")
      END_OUTLINE_DATA
  */
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("T2"."ID"="T1"."ID" AND "T2"."NAME"="T1"."NAME")
   7 - access("T2"."ID"="T1"."ID")
   8 - filter("T2"."NAME"="T1"."NAME")

Note
-----
   - this is an adaptive plan (rows marked '-' are inactive)

9. in ,exists后一点点小问题会漏掉id相等,name为NULL的情况,继续测试:
insert into t2 values (11,null);
update t1 set name=null where id=11;
commt;

SCOTT@test01p> select /*+ OPT_PARAM('_convert_set_to_join' 'true') */ * from t1 intersect select * from t2;
        ID NAME
---------- --------------------
         7 testtest
         8 testtest
         2 testtest
         5 testtest
         1 testtest
         3 testtest
         6 testtest
        10 testtest
         4 testtest
         9 testtest
        11
11 rows selected.
--实际上看前面的执行计划,就很容易理解filter(SYS_OP_MAP_NONNULL("T1"."NAME")=SYS_OP_MAP_NONNULL("T2"."NAME"))的含义.

SCOTT@test01p> select id,name from t1 where exists ( select null from t2 where t2.id=t1.id and t2.name =t1.name);
        ID NAME
---------- --------------------
         1 testtest
         2 testtest
         3 testtest
         4 testtest
         5 testtest
         6 testtest
         7 testtest
         8 testtest
         9 testtest
        10 testtest

10 rows selected.

SCOTT@test01p> select id,name from t1 where (id,name) in ( select id,name from t2);
        ID NAME
---------- --------------------
         1 testtest
         2 testtest
         3 testtest
         4 testtest
         5 testtest
         6 testtest
         7 testtest
         8 testtest
         9 testtest
        10 testtest
10 rows selected.

--如果使用in,exists,写成这样.
select id,name from t1 where (id,name) in ( select id,name from t2)
union all
select id,name from t1 where (id) in ( select id from t2 where t2.name is null) and  t1.name is null ;

select id,name from t2 where (id,name) in ( select id,name from t2)
union all
select id,name from t2 where (id) in ( select id from t1 where t1.name is null) and  t2.name is null ;

select id,name from t1 where exists ( select null from t2 where t2.id=t1.id and (t2.name =t1.name or (t1.name is null and t2.name is null)));

select id,name from t2 where exists ( select null from t1 where t1.id=t2.id and (t1.name =t2.name or (t2.name is null and t1.name is null)));

12.猜测函数SYS_OP_MAP_NONNULL的意义:
SCOTT@test01p> select SYS_OP_MAP_NONNULL(id) c10 ,SYS_OP_MAP_NONNULL(name) ,t2.*,dump(id,16) c20,dump(name,16) c40 from t2;
C10        SYS_OP_MAP_NONNULL_NAM         ID NAME                 C20                  C40
---------- ---------------------- ---------- -------------------- -------------------- ----------------------------------------
C10200     746573747465737400              1 testtest             Typ=2 Len=2: c1,2    Typ=1 Len=8: 74,65,73,74,74,65,73,74
C10300     746573747465737400              2 testtest             Typ=2 Len=2: c1,3    Typ=1 Len=8: 74,65,73,74,74,65,73,74
C10400     746573747465737400              3 testtest             Typ=2 Len=2: c1,4    Typ=1 Len=8: 74,65,73,74,74,65,73,74
C10500     746573747465737400              4 testtest             Typ=2 Len=2: c1,5    Typ=1 Len=8: 74,65,73,74,74,65,73,74
C10600     746573747465737400              5 testtest             Typ=2 Len=2: c1,6    Typ=1 Len=8: 74,65,73,74,74,65,73,74
C10700     746573747465737400              6 testtest             Typ=2 Len=2: c1,7    Typ=1 Len=8: 74,65,73,74,74,65,73,74
C10800     746573747465737400              7 testtest             Typ=2 Len=2: c1,8    Typ=1 Len=8: 74,65,73,74,74,65,73,74
C10900     746573747465737400              8 testtest             Typ=2 Len=2: c1,9    Typ=1 Len=8: 74,65,73,74,74,65,73,74
C10A00     746573747465737400              9 testtest             Typ=2 Len=2: c1,a    Typ=1 Len=8: 74,65,73,74,74,65,73,74
C10B00     746573747465737400             10 testtest             Typ=2 Len=2: c1,b    Typ=1 Len=8: 74,65,73,74,74,65,73,74
C10C00     FF                             11                      Typ=2 Len=2: c1,c    NULL

11 rows selected.

--从输出结果应该猜到大概.

时间: 2024-09-20 11:58:45

[20140823]12c join convert连接转换.txt的相关文章

[20170310]oracle内部时间戳的转换.txt

[20170310]oracle内部时间戳的转换.txt --//昨天验证v$archived_log.stamp时,链接如下http://blog.itpub.net/267265/viewspace-2135044/,才发现自己以前犯了严重错误. --//想起http://www.juliandyke.com/Diagnostics/Dumps/RedoLogs.php转储redo时time参数使用: TIME The minimum and maximum time is a decima

[20160219]关于连接顺序.txt

[20160219]关于连接顺序.txt --今天被问一个问题,如果使用外连接的情况,连接顺序可以改变吗?我只能说我给测试看看,再回答这个问题: 1.环境: SCOTT@book> @ &r/ver1 PORT_STRING                    VERSION        BANNER ------------------------------ -------------- ------------------------------------------------

[20140823]在sqlplus使用copy注意.txt

[20140823]在sqlplus使用copy注意.txt --有时候使用copy来复制表数据,但是前几天我的测试遇到一些小问题,做一个记录,总之还是小心注意这些细节. SCOTT@test01p> @ver BANNER                                                                               CON_ID ----------------------------------------------------

JavaScript通过join函数连接数组里所有元素的方法

 这篇文章主要介绍了JavaScript通过join函数连接数组里所有元素的方法,实例分析了javascript中join函数的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下     本文实例讲述了JavaScript通过join函数连接数组里所有元素的方法.分享给大家供大家参考.具体实现方法如下: ? 1 2 3 4 5 <script type="text/javascript"> var days = ["Sunday","Mond

hibernate-Hibernate执行sybase数据库的convert()函数转换日期为1

问题描述 Hibernate执行sybase数据库的convert()函数转换日期为1 我sql中使用到了convert(char(9),orderdate,112),orderdate是一个日期,但是我用hibernate执行之后结果都是1 SQLQuery query = session.createSQLQuery(sql); List<Object[]> list = query.list(); Object[] obj = list.get(0); ..... String orde

mysql left join 左连接查询关联n多张表

left join 左连接即以左表为基准,显示坐标所有的行,右表与左表关联的数据会显示,不关联的则不显示.关键字为left join on. **基本用法如下:  select table a left join table b on a.id = b.ta_id** 注意:️其中on后面关联的字段应该是同一字段(两表关联的外键) ️由于以左表为基准,左表一条记录如果对应右表多条记录,那查出的数据中右表的数据也只显示一条,如果要都显示,可以用group_contact()将字段用逗号隔开显示在一

java中pdfbox-pdfbox转换txt的一些问题

问题描述 pdfbox转换txt的一些问题 j今天试着用网上一些pdfbox的代码转换文档,发现:如pdf文档是纯文字型就能转换成功 ,要是里面有图片,就不能转换 解决方案 pdfbox转换txt--1 解决方案二: http://blog.csdn.net/loverszhaokai/article/details/5769700

JavaScript通过join函数连接数组里所有元素的方法_javascript技巧

本文实例讲述了JavaScript通过join函数连接数组里所有元素的方法.分享给大家供大家参考.具体实现方法如下: <script type="text/javascript"> var days = ["Sunday","Monday","Tuesday","Wednesday", "Thursday","Friday","Saturday&

[20170825]11G备库启用DRCP连接3.txt

[20170825]11G备库启用DRCP连接3.txt --//昨天测试了11G备库启用DRCP连接,要设置alter system set audit_trail=none scope=spfile ; --//参考链接http://blog.itpub.net/267265/viewspace-2144036/. --//在测试过程中我遇到1个奇怪问题,就是如果主库没有打开drcp,备库执行exec dbms_connection_pool.start_pool();失败. --//今天分