Oracle之三大连接的使用限制,nl、hash、merge

来源:互联网 发布:klairs淘宝官网 编辑:程序博客网 时间:2024/05/22 08:04

知识点: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"))


阅读全文
0 0
原创粉丝点击