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"))