1. 程式人生 > >Oracle之三大連線的使用限制,nl、hash、merge

Oracle之三大連線的使用限制,nl、hash、merge

知識點:hitns的  ->  

/*+ leading(t1) use_nl(t2) */

/*+ leading(t1) use_merge(t2)*/ 

/*+ leading(t1) use_hash(t2)*/ 

t1:驅動表,t2外表。

解析:nl連線應用廣泛

等值、不等值、like等都可以

hash:經典的等值連線,不等值、like等不行

merge:不等值可以,like、等值不行

nll驗:


/*
  結論:Nested Loops Join支援大於,小於,不等,LIKE等連線條件,可以說沒有受到任何限制! 
  其實本次也無需做試驗,看完隨後的HASH連線和排序合併連線的試驗,也能明白! 
*/


--環境構造
--研究Nested Loops Join訪問次數前準備工作
DROP TABLE t1 CASCADE CONSTRAINTS PURGE; 
DROP TABLE t2 CASCADE CONSTRAINTS PURGE; 
CREATE TABLE t1 (
     id NUMBER NOT NULL,
     n NUMBER,
     contents VARCHAR2(4000)
   )
   ; 
CREATE TABLE t2 (
     id NUMBER NOT NULL,
     t1_id NUMBER NOT NULL,
     n NUMBER,
     contents VARCHAR2(4000)
   )
   ; 
execute dbms_random.seed(0); 
INSERT INTO t1
     SELECT  rownum,  rownum, dbms_random.string('a', 50)
       FROM dual
     CONNECT BY level <= 100
      ORDER BY dbms_random.random; 
INSERT INTO t2 SELECT rownum, rownum, rownum, dbms_random.string('b', 50) FROM dual CONNECT BY level <= 100000
    ORDER BY dbms_random.random; 
COMMIT; 
select count(*) from t1;
select count(*) from t2;


set linesize 1000
set autotrace traceonly explain
SELECT  /*+ leading(t1) use_nl(t2) */ *
  FROM t1, t2
  WHERE t1.id > t2.t1_id
  AND t1.n = 19;
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    50 |  6150 |   276   (1)| 00:00:04 |
|   1 |  NESTED LOOPS      |      |    50 |  6150 |   276   (1)| 00:00:04 |
|*  2 |   TABLE ACCESS FULL| T1   |     1 |    57 |     3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   |    50 |  3300 |   273   (1)| 00:00:04 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("T1"."N"=19)
   3 - filter("T1"."ID">"T2"."T1_ID")
   
   
SELECT  /*+ leading(t1) use_nl(t2) */ *
  FROM t1, t2
  WHERE t1.id < t2.t1_id
  AND t1.n = 19;   
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      | 99950 |    11M|   276   (1)| 00:00:04 |
|   1 |  NESTED LOOPS      |      | 99950 |    11M|   276   (1)| 00:00:04 |
|*  2 |   TABLE ACCESS FULL| T1   |     1 |    57 |     3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   | 99950 |  6442K|   273   (1)| 00:00:04 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("T1"."N"=19)
   3 - filter("T1"."ID"<"T2"."T1_ID") 
  
   
SELECT  /*+ leading(t1) use_nl(t2) */ *
  FROM t1, t2
  WHERE t1.id <> t2.t1_id
  AND t1.n = 19;     
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      | 99999 |    11M|   276   (1)| 00:00:04 |
|   1 |  NESTED LOOPS      |      | 99999 |    11M|   276   (1)| 00:00:04 |
|*  2 |   TABLE ACCESS FULL| T1   |     1 |    57 |     3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   | 99999 |  6445K|   273   (1)| 00:00:04 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("T1"."N"=19)
   3 - filter("T1"."ID"<>"T2"."T1_ID")  
   
   
SELECT  /*+ leading(t1) use_nl(t2) */ *
  FROM t1, t2
  WHERE t1.id like t2.t1_id
  AND t1.n = 19;    
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |  5000 |   600K|   276   (1)| 00:00:04 |
|   1 |  NESTED LOOPS      |      |  5000 |   600K|   276   (1)| 00:00:04 |
|*  2 |   TABLE ACCESS FULL| T1   |     1 |    57 |     3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   |  5000 |   322K|   273   (1)| 00:00:04 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("T1"."N"=19)
   3 - filter(TO_CHAR("T1"."ID") LIKE TO_CHAR("T2"."T1_ID"))

hash實驗:

/*
  結論:Hash Join不支援大於,小於,不等,LIKE等連線條件!  
*/


--環境構造
--研究Nested Loops Join訪問次數前準備工作
DROP TABLE t1 CASCADE CONSTRAINTS PURGE; 
DROP TABLE t2 CASCADE CONSTRAINTS PURGE; 
CREATE TABLE t1 (
     id NUMBER NOT NULL,
     n NUMBER,
     contents VARCHAR2(4000)
   )
   ; 
CREATE TABLE t2 (
     id NUMBER NOT NULL,
     t1_id NUMBER NOT NULL,
     n NUMBER,
     contents VARCHAR2(4000)
   )
   ; 
execute dbms_random.seed(0); 
INSERT INTO t1
     SELECT  rownum,  rownum, dbms_random.string('a', 50)
       FROM dual
     CONNECT BY level <= 100
      ORDER BY dbms_random.random; 
INSERT INTO t2 SELECT rownum, rownum, rownum, dbms_random.string('b', 50) FROM dual CONNECT BY level <= 100000
    ORDER BY dbms_random.random; 
COMMIT; 
select count(*) from t1;
select count(*) from t2;


set linesize 1000
set autotrace traceonly explain
SELECT /*+ leading(t1) use_hash(t2)*/ *
  FROM t1, t2
  WHERE t1.id > t2.t1_id
  AND t1.n = 19;
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    50 |  6150 |   276   (1)| 00:00:04 |
|   1 |  NESTED LOOPS      |      |    50 |  6150 |   276   (1)| 00:00:04 |
|*  2 |   TABLE ACCESS FULL| T1   |     1 |    57 |     3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   |    50 |  3300 |   273   (1)| 00:00:04 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("T1"."N"=19)
   3 - filter("T1"."ID">"T2"."T1_ID")
   
   
SELECT /*+ leading(t1) use_hash(t2)*/ *
  FROM t1, t2
  WHERE t1.id < t2.t1_id
  AND t1.n = 19;   
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      | 99950 |    11M|   276   (1)| 00:00:04 |
|   1 |  NESTED LOOPS      |      | 99950 |    11M|   276   (1)| 00:00:04 |
|*  2 |   TABLE ACCESS FULL| T1   |     1 |    57 |     3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   | 99950 |  6442K|   273   (1)| 00:00:04 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("T1"."N"=19)
   3 - filter("T1"."ID"<"T2"."T1_ID")  
  
   
SELECT /*+ leading(t1) use_hash(t2)*/ *
  FROM t1, t2
  WHERE t1.id <> t2.t1_id
  AND t1.n = 19;     
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      | 99999 |    11M|   276   (1)| 00:00:04 |
|   1 |  NESTED LOOPS      |      | 99999 |    11M|   276   (1)| 00:00:04 |
|*  2 |   TABLE ACCESS FULL| T1   |     1 |    57 |     3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   | 99999 |  6445K|   273   (1)| 00:00:04 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("T1"."N"=19)
   3 - filter("T1"."ID"<>"T2"."T1_ID")  
   
   
SELECT /*+ leading(t1) use_hash(t2)*/ *
  FROM t1, t2
  WHERE t1.id like t2.t1_id
  AND t1.n = 19;    
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |  5000 |   600K|   276   (1)| 00:00:04 |
|   1 |  NESTED LOOPS      |      |  5000 |   600K|   276   (1)| 00:00:04 |
|*  2 |   TABLE ACCESS FULL| T1   |     1 |    57 |     3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   |  5000 |   322K|   273   (1)| 00:00:04 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("T1"."N"=19)
   3 - filter(TO_CHAR("T1"."ID") LIKE TO_CHAR("T2"."T1_ID"))  

merge實驗:

/*
  結論:Merge Sort Join不支援不等,LIKE等連線條件,卻支援大於,小於的連線條件。  
*/


--環境構造
--研究Nested Loops Join訪問次數前準備工作
DROP TABLE t1 CASCADE CONSTRAINTS PURGE; 
DROP TABLE t2 CASCADE CONSTRAINTS PURGE; 
CREATE TABLE t1 (
     id NUMBER NOT NULL,
     n NUMBER,
     contents VARCHAR2(4000)
   )
   ; 
CREATE TABLE t2 (
     id NUMBER NOT NULL,
     t1_id NUMBER NOT NULL,
     n NUMBER,
     contents VARCHAR2(4000)
   )
   ; 
execute dbms_random.seed(0); 
INSERT INTO t1
     SELECT  rownum,  rownum, dbms_random.string('a', 50)
       FROM dual
     CONNECT BY level <= 100
      ORDER BY dbms_random.random; 
INSERT INTO t2 SELECT rownum, rownum, rownum, dbms_random.string('b', 50) FROM dual CONNECT BY level <= 100000
    ORDER BY dbms_random.random; 
COMMIT; 
select count(*) from t1;
select count(*) from t2;


set linesize 1000
set autotrace traceonly explain
SELECT /*+ leading(t1) use_merge(t2)*/ *
  FROM t1, t2
  WHERE t1.id > t2.t1_id
  AND t1.n = 19;
------------------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |    50 |  6150 |       |  1852   (1)| 00:00:23 |
|   1 |  MERGE JOIN         |      |    50 |  6150 |       |  1852   (1)| 00:00:23 |
|   2 |   SORT JOIN         |      |     1 |    57 |       |     4  (25)| 00:00:01 |
|*  3 |    TABLE ACCESS FULL| T1   |     1 |    57 |       |     3   (0)| 00:00:01 |
|*  4 |   SORT JOIN         |      |   100K|  6445K|    15M|  1848   (1)| 00:00:23 |
|   5 |    TABLE ACCESS FULL| T2   |   100K|  6445K|       |   273   (1)| 00:00:04 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - filter("T1"."N"=19)
   4 - access(INTERNAL_FUNCTION("T1"."ID")>INTERNAL_FUNCTION("T2"."T1_ID"))
       filter(INTERNAL_FUNCTION("T1"."ID")>INTERNAL_FUNCTION("T2"."T1_ID"))
   
   
SELECT /*+ leading(t1) use_merge(t2)*/ *
  FROM t1, t2
  WHERE t1.id < t2.t1_id
  AND t1.n = 19;   
------------------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      | 99950 |    11M|       |  1852   (1)| 00:00:23 |
|   1 |  MERGE JOIN         |      | 99950 |    11M|       |  1852   (1)| 00:00:23 |
|   2 |   SORT JOIN         |      |     1 |    57 |       |     4  (25)| 00:00:01 |
|*  3 |    TABLE ACCESS FULL| T1   |     1 |    57 |       |     3   (0)| 00:00:01 |
|*  4 |   SORT JOIN         |      |   100K|  6445K|    15M|  1848   (1)| 00:00:23 |
|   5 |    TABLE ACCESS FULL| T2   |   100K|  6445K|       |   273   (1)| 00:00:04 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - filter("T1"."N"=19)
   4 - access("T1"."ID"<"T2"."T1_ID")
       filter("T1"."ID"<"T2"."T1_ID")
  
   
SELECT /*+ leading(t1) use_merge(t2)*/ *
  FROM t1, t2
  WHERE t1.id <> t2.t1_id
  AND t1.n = 19;     
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      | 99999 |    11M|   276   (1)| 00:00:04 |
|   1 |  NESTED LOOPS      |      | 99999 |    11M|   276   (1)| 00:00:04 |
|*  2 |   TABLE ACCESS FULL| T1   |     1 |    57 |     3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   | 99999 |  6445K|   273   (1)| 00:00:04 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("T1"."N"=19)
   3 - filter("T1"."ID"<>"T2"."T1_ID")
   
  
   
SELECT /*+ leading(t1) use_merge(t2)*/ *
  FROM t1, t2
  WHERE t1.id like t2.t1_id
  AND t1.n = 19;    
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |  5000 |   600K|   276   (1)| 00:00:04 |
|   1 |  NESTED LOOPS      |      |  5000 |   600K|   276   (1)| 00:00:04 |
|*  2 |   TABLE ACCESS FULL| T1   |     1 |    57 |     3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   |  5000 |   322K|   273   (1)| 00:00:04 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("T1"."N"=19)
   3 - filter(TO_CHAR("T1"."ID") LIKE TO_CHAR("T2"."T1_ID"))