1. 程式人生 > 其它 >Oracle NL半連線反連線被驅動表的執行次數探究

Oracle NL半連線反連線被驅動表的執行次數探究

Oracle NL半連線反連線被驅動表的執行次數探究

正常的NL中,被驅動表的執行次數為驅動表的結果集行數。

對於反連線和半連線,從探究實驗的結果看,被驅動表的執行次數為驅動表的連線條件的去重後的值。

具體看如下測試。

建立測試表

10:43:26 ZKM@testdb(476)> create table t1 as select * from dba_objects;

Table created.

Elapsed: 00:00:00.17
10:43:31 ZKM@testdb(476)> create table t2 as select * from dba_objects;

Table created. Elapsed: 00:00:00.17

反連線語句:select count(*) from t1 where not exists ( select /*+ nl_aj */ 1 from t2 where t1.owner=t2.owner);

半連線語句:select count(*) from t1 where exists ( select /*+ nl_sj */ 1 from t2 where t1.owner=t2.owner);

反連線/半連線次數:distinct後值為16

10:43:34 ZKM@testdb(476)> select count
(distinct owner) from t1; COUNT(DISTINCTOWNER) -------------------- 16 Elapsed: 00:00:00.03 10:43:40 ZKM@testdb(476)> select count(*) from t1 where not exists ( select /*+ nl_aj */ 1 from t2 where t1.owner=t2.owner); COUNT(*) ---------- 0 Elapsed: 00:00:00.07 10:43:44 ZKM@testdb(476)>
select * from table(dbms_xplan.display_cursor(null,null,'allstats last')); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------ SQL_ID 1wkqm7d8319gw, child number 1 ------------------------------------- select count(*) from t1 where not exists ( select /*+ nl_aj */ 1 from t2 where t1.owner=t2.owner) Plan hash value: 4091582738 ----------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | ----------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.04 | 2851 | 70 | | 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.04 | 2851 | 70 | | 2 | NESTED LOOPS ANTI | | 1 | 16486 | 0 |00:00:00.03 | 2851 | 70 | | 3 | TABLE ACCESS FULL| T1 | 1 | 16486 | 19031 |00:00:00.01 | 259 | 0 | |* 4 | TABLE ACCESS FULL| T2 | 16 | 1 | 16 |00:00:00.02 | 2592 | 70 | ----------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - filter("T1"."OWNER"="T2"."OWNER") Note ----- - dynamic sampling used for this statement (level=2) 26 rows selected. Elapsed: 00:00:00.02 10:43:48 ZKM@testdb(476)> select count(*) from t1 where exists ( select /*+ nl_sj */ 1 from t2 where t1.owner=t2.owner); COUNT(*) ---------- 19031 Elapsed: 00:00:00.03 10:44:13 ZKM@testdb(476)> select * from table(dbms_xplan.display_cursor(null,null,'allstats last')); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------- SQL_ID a96rmsu79t8pk, child number 0 ------------------------------------- select count(*) from t1 where exists ( select /*+ nl_sj */ 1 from t2 where t1.owner=t2.owner) Plan hash value: 2128633509 -------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.03 | 2851 | | 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.03 | 2851 | | 2 | NESTED LOOPS SEMI | | 1 | 12681 | 19031 |00:00:00.03 | 2851 | | 3 | TABLE ACCESS FULL| T1 | 1 | 16486 | 19031 |00:00:00.01 | 259 | |* 4 | TABLE ACCESS FULL| T2 | 16 | 15680 | 16 |00:00:00.01 | 2592 | -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - filter("T1"."OWNER"="T2"."OWNER") Note ----- - dynamic sampling used for this statement (level=2) 26 rows selected. Elapsed: 00:00:00.02

反連線/半連線次數:distinct後值為17

10:44:35 ZKM@testdb(476)> update t1 set owner='OTHERNAME' where object_id=35950;

1 row updated.

Elapsed: 00:00:00.00
10:44:36 ZKM@testdb(476)> commit;

Commit complete.

Elapsed: 00:00:00.00
10:44:41 ZKM@testdb(476)> select count(distinct owner) from t1;

COUNT(DISTINCTOWNER)
--------------------
                  17

Elapsed: 00:00:00.01
10:44:44 ZKM@testdb(476)> select count(*) from t1 where not exists ( select /*+ nl_aj */ 1 from t2 where t1.owner=t2.owner);

  COUNT(*)
----------
         1

Elapsed: 00:00:00.03
10:44:52 ZKM@testdb(476)> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------
SQL_ID  1wkqm7d8319gw, child number 1
-------------------------------------
select count(*) from t1 where not exists ( select /*+ nl_aj */ 1 from
t2 where t1.owner=t2.owner)

Plan hash value: 4091582738

--------------------------------------------------------------------------------------
| Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |      1 |        |      1 |00:00:00.03 |    3110 |
|   1 |  SORT AGGREGATE     |      |      1 |      1 |      1 |00:00:00.03 |    3110 |
|   2 |   NESTED LOOPS ANTI |      |      1 |  16486 |      1 |00:00:00.03 |    3110 |
|   3 |    TABLE ACCESS FULL| T1   |      1 |  16486 |  19031 |00:00:00.01 |     259 |
|*  4 |    TABLE ACCESS FULL| T2   |     17 |      1 |     16 |00:00:00.02 |    2851 |
--------------------------------------------------------------------------------------

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

   4 - filter("T1"."OWNER"="T2"."OWNER")

Note
-----
   - dynamic sampling used for this statement (level=2)


26 rows selected.

Elapsed: 00:00:00.03
10:44:54 ZKM@testdb(476)> select count(*) from t1 where exists ( select /*+ nl_sj */ 1 from t2 where t1.owner=t2.owner);

  COUNT(*)
----------
     19030

Elapsed: 00:00:00.04
10:45:00 ZKM@testdb(476)> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------
SQL_ID  a96rmsu79t8pk, child number 0
-------------------------------------
select count(*) from t1 where exists ( select /*+ nl_sj */ 1 from t2
where t1.owner=t2.owner)

Plan hash value: 2128633509

--------------------------------------------------------------------------------------
| Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |      1 |        |      1 |00:00:00.03 |    3110 |
|   1 |  SORT AGGREGATE     |      |      1 |      1 |      1 |00:00:00.03 |    3110 |
|   2 |   NESTED LOOPS SEMI |      |      1 |  12681 |  19030 |00:00:00.03 |    3110 |
|   3 |    TABLE ACCESS FULL| T1   |      1 |  16486 |  19031 |00:00:00.01 |     259 |
|*  4 |    TABLE ACCESS FULL| T2   |     17 |  15680 |     16 |00:00:00.01 |    2851 |
--------------------------------------------------------------------------------------

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

   4 - filter("T1"."OWNER"="T2"."OWNER")

Note
-----
   - dynamic sampling used for this statement (level=2)


26 rows selected.

Elapsed: 00:00:00.02

反連線/半連線次數:distinct後值為1

10:46:38 ZKM@testdb(476)> update t1 set owner='OTHERNAME';

19031 rows updated.

Elapsed: 00:00:00.62
10:46:40 ZKM@testdb(476)> commit;

Commit complete.

Elapsed: 00:00:00.01
10:46:43 ZKM@testdb(476)> select count(distinct owner) from t1;

COUNT(DISTINCTOWNER)
--------------------
                   1

Elapsed: 00:00:00.00
10:46:46 ZKM@testdb(476)> select count(*) from t1 where not exists ( select /*+ nl_aj */ 1 from t2 where t1.owner=t2.owner);

  COUNT(*)
----------
     19031

Elapsed: 00:00:00.02
10:46:52 ZKM@testdb(476)> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------
SQL_ID  1wkqm7d8319gw, child number 1
-------------------------------------
select count(*) from t1 where not exists ( select /*+ nl_aj */ 1 from
t2 where t1.owner=t2.owner)

Plan hash value: 4091582738

--------------------------------------------------------------------------------------
| Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |      1 |        |      1 |00:00:00.02 |     518 |
|   1 |  SORT AGGREGATE     |      |      1 |      1 |      1 |00:00:00.02 |     518 |
|   2 |   NESTED LOOPS ANTI |      |      1 |  16486 |  19031 |00:00:00.02 |     518 |
|   3 |    TABLE ACCESS FULL| T1   |      1 |  16486 |  19031 |00:00:00.01 |     259 |
|*  4 |    TABLE ACCESS FULL| T2   |      1 |      1 |      0 |00:00:00.01 |     259 |
--------------------------------------------------------------------------------------

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

   4 - filter("T1"."OWNER"="T2"."OWNER")

Note
-----
   - dynamic sampling used for this statement (level=2)


26 rows selected.

Elapsed: 00:00:00.02
10:46:52 ZKM@testdb(476)> select count(*) from t1 where exists ( select /*+ nl_sj */ 1 from t2 where t1.owner=t2.owner);

  COUNT(*)
----------
         0

Elapsed: 00:00:00.01
10:47:06 ZKM@testdb(476)> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------
SQL_ID  a96rmsu79t8pk, child number 0
-------------------------------------
select count(*) from t1 where exists ( select /*+ nl_sj */ 1 from t2
where t1.owner=t2.owner)

Plan hash value: 2128633509

--------------------------------------------------------------------------------------
| Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |      1 |        |      1 |00:00:00.01 |     518 |
|   1 |  SORT AGGREGATE     |      |      1 |      1 |      1 |00:00:00.01 |     518 |
|   2 |   NESTED LOOPS SEMI |      |      1 |  12681 |      0 |00:00:00.01 |     518 |
|   3 |    TABLE ACCESS FULL| T1   |      1 |  16486 |  19031 |00:00:00.01 |     259 |
|*  4 |    TABLE ACCESS FULL| T2   |      1 |  15680 |      0 |00:00:00.01 |     259 |
--------------------------------------------------------------------------------------

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

   4 - filter("T1"."OWNER"="T2"."OWNER")

Note
-----
   - dynamic sampling used for this statement (level=2)


26 rows selected.

Elapsed: 00:00:00.02

總結如下:

count(distinct) 17 16 1
驅動表訪問次數 1 1 1
被驅動表訪問次數 17 16 1