一、表访问方式
CBO基础概念中有讲到,访问表的方式有两种:全表扫描和ROWID扫描。
全表扫描的执行计划:TABLE ACCESS FULL
ROWID扫描对应执行计划:TABLE ACCESS BY USER ROWID 或 TABLE ACCESS BY INDEX ROWID
通过例子说明
(一)、全表扫描方式
select empno,ename from scott.emp select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID 6c0fp61y99tuw, child number 0 ------------------------------------- select empno,ename from scott.emp Plan hash value: 3956160932 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 3 (100)| | | 1 | TABLE ACCESS FULL| EMP | 14 | 140 | 3 (0)| 00:00:01 | --------------------------------------------------------------------------
(二)、rowid访问方式
1、TABLE ACCESS BY USER ROWID
select empno,ename from scott.emp where rowid=‘AAASZHAAEAAAACXAAA‘ select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID 99f9cvxt33nzy, child number 0 ------------------------------------- select empno,ename from scott.emp where rowid=‘AAASZHAAEAAAACXAAA‘ Plan hash value: 1116584662 ----------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 1 (100)| | | 1 | TABLE ACCESS BY USER ROWID| EMP | 1 | 22 | 1 (0)| 00:00:01 | -----------------------------------------------------------------------------------
2、TABLE ACCESS BY INDEX ROWID
select empno,ename from scott.emp where empno=7521 select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID 69nxfycyppq7m, child number 0 ------------------------------------- select empno,ename from scott.emp where empno=7521 Plan hash value: 2949544139 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 1 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 10 | 1 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | PK_EMP | 1 | | 0 (0)| | -------------------------------------------------------------------------------------- ...
二、B*树访问方式
索引唯一扫描、索引范围扫描、索引全扫描、索引快速扫描、索引跳跃式扫描
以上这些执行计划执行计划相对应
- 索引唯一扫描:INDEX UNIQUE SCAN
- 索引范围扫描:INDEX RANGE SCAN
- 索引全扫描:INDEX FULL SCAN
- 索引快速全扫描:INDEX FAST FULL SCAN
- 索引跳跃式扫描:INDEX SKIP SCAN
例子说明
(一)、索引唯一扫描:INDEX UNIQUE SCAN
select empno,ename from scott.emp where empno=7521 select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID 69nxfycyppq7m, child number 0 ------------------------------------- select empno,ename from scott.emp where empno=7521 Plan hash value: 2949544139 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 1 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 10 | 1 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | PK_EMP | 1 | | 0 (0)| | --------------------------------------------------------------------------------------
通过唯一索引的方式获取rowid访问表中的以rowid的方式
(二)、索引范围扫描:INDEX RANGE SCAN
select empno,ename from scott.emp where empno>=7521 and empno<=8521 select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID 95m0uw0yxc10w, child number 0 ------------------------------------- select empno,ename from scott.emp where empno>=7521 and empno<=8521 Plan hash value: 169057108 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| EMP | 11 | 110 | 2 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | PK_EMP | 11 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("EMPNO">=7521 AND "EMPNO"<=8521)
谓词中存在大于、小于的访问方式时,并且这个谓词建议过索引,基本采用索引范围扫描的方式
(三)、索引全扫描:INDEX FULL SCAN
select empno,ename from scott.emp order by empno select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID 3bt7b5h1rxh6z, child number 0 ------------------------------------- select empno,ename from scott.emp order by empno Plan hash value: 4170700152 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| EMP | 14 | 140 | 2 (0)| 00:00:01 | | 2 | INDEX FULL SCAN | PK_EMP | 14 | | 1 (0)| 00:00:01 | --------------------------------------------------------------------------------------
当索引列的定义可以为null
create index ind_EMP_JOB ON scott.emp(JOB); select empno,ename from scott.emp order by job select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID cnpptzn6mshrb, child number 0 ------------------------------------- select empno,ename from scott.emp order by job Plan hash value: 150391907 --------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 4 (100)| | | 1 | SORT ORDER BY | | 14 | 252 | 4 (25)| 00:00:01 | | 2 | TABLE ACCESS FULL| EMP | 14 | 252 | 3 (0)| 00:00:01 | ---------------------------------------------------------------------------
发现如果JOB列定义可以为空的话,order by 是不会走索引的。
调整列的属性,不能为空,在查看执行计划
alter table scott.emp modify(job not null) select empno,ename from scott.emp order by job select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID cnpptzn6mshrb, child number 0 ------------------------------------- select empno,ename from scott.emp order by job Plan hash value: 157317628 ------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| EMP | 14 | 252 | 2 (0)| 00:00:01 | | 2 | INDEX FULL SCAN | IND_EMP_JOB | 14 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------------
(四)、索引快速全扫描:INDEX FAST FULL SCAN
select /*+index_ffs(a ind_EMP_JOB)*/ job from scott.emp a select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID 3hu16hz75qkhu, child number 0 ------------------------------------- select /*+index_ffs(a ind_EMP_JOB)*/ job from scott.emp a Plan hash value: 2520590889 ------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | INDEX FAST FULL SCAN| IND_EMP_JOB | 14 | 112 | 2 (0)| 00:00:01 | ------------------------------------------------------------------------------------
这里使用HINT,强制提示优化器走fast索引的方式
(五)、索引跳跃式扫描:INDEX SKIP SCAN
用于复合索引中的,非索引前导列的访问
create index ind_EMP_JENAME ON scott.emp(JOB,ename); select empno,ename from scott.emp where ename=‘ALLEN‘ SQL_ID bdfu46xwtg0qk, child number 0 ------------------------------------- select empno,ename from scott.emp where ename=‘ALLEN‘ Plan hash value: 878294805 ---------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 2 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 10 | 2 (0)| 00:00:01 | |* 2 | INDEX SKIP SCAN | IND_EMP_JENAME | 1 | | 1 (0)| 00:00:01 | ---------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("ENAME"=‘ALLEN‘) filter("ENAME"=‘ALLEN‘)
三、位图索引访问的方式
适用于数据仓库,不适用OLTP系统,物理存储结构类似B*数索引,对应rowid的上限、rowid的下限、位图段。
对于oracle数据库中的位图索引而言,他是没有行锁这个概念的,要锁就锁索引行的整个位图段,而多个数据行可能对应同一个索引行的位图段,这个锁的粒度就决定了位图索引不适用于高并发并频繁修改的OLTP系统,在OLTP系统中,很容易产生死锁。
- 位图索引单键值扫描:BITMAP INDEX SINGLE VALUE
- 位图索引范围扫描: BITMAP INDEX RANGE SCAN
- 位图索引全扫描: BITMAP INDEX FULL SCAN
- 位图索引快速全扫描: BITMAP INDEX FAST FULL SCAN
- 位图按位与: BITMAP AND
- 位图按位或: BITMAP OR
- 位图按位减: BITMAP MINUS
(一)、构造一张表,测试位图索引
Create table test_normal (empno number(10), ename varchar2(30), sal number(10)) TABLESPACE GLL01; Begin For i in 1..1000000 Loop Insert into test_normal values(i, dbms_random.string(‘U‘,30), dbms_random.value(1000,7000)); If mod(i, 10000) = 0 then Commit; End if; End loop; End; create bitmap index normal_empno_bmx on test_normal(empno) TABLESPACE GLL01; create bitmap index normal_empno_sal on test_normal(sal) TABLESPACE GLL01; EXECUTE DBMS_STATS.GATHER_TABLE_STATS(‘SYS‘,‘TEST_NORMAL‘,CASCADE=>TRUE);
(二)、位图索引单键值扫描:BITMAP INDEX SINGLE VALUE
select * from test_normal where empno=1000 select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID 343wc0yvq4cc9, child number 0 ------------------------------------- select * from test_normal where empno=1000 Plan hash value: 4267925254 ------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 3 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID | TEST_NORMAL | 1 | 40 | 3 (0)| 00:00:01 | | 2 | BITMAP CONVERSION TO ROWIDS| | | | | | |* 3 | BITMAP INDEX SINGLE VALUE | NORMAL_EMPNO_BMX | | | | | ------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("EMPNO"=1000)
(三)、位图索引范围扫描: BITMAP INDEX RANGE SCAN
select * from test_normal where empno>=50 and empno<=2000 select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID 34p69q6q4wqxx, child number 0 ------------------------------------- select * from test_normal where empno>=50 and empno<=2000 Plan hash value: 641040856 ------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 362 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID | TEST_NORMAL | 1952 | 78080 | 362 (0)| 00:00:05 | | 2 | BITMAP CONVERSION TO ROWIDS| | | | | | |* 3 | BITMAP INDEX RANGE SCAN | NORMAL_EMPNO_BMX | | | | | ------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("EMPNO">=50 AND "EMPNO"<=2000)
(四)、位图索引全扫描: BITMAP INDEX FULL SCAN
select /*+index(a normal_empno_bmx)*/ a.empno from test_normal a select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID cmxdf5ry1gvw1, child number 0 ------------------------------------- select /*+index(a normal_empno_bmx)*/ a.empno from test_normal a Plan hash value: 220257735 ------------------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | | | 3496 (100)| | | 1 | BITMAP CONVERSION TO ROWIDS| | 1000K| 4882K| 3496 (1)| 00:00:42 | | 2 | BITMAP INDEX FULL SCAN | NORMAL_EMPNO_BMX | | | | | ------------------------------------------------------------------------------------------------
(五)、位图索引快速全扫描: BITMAP INDEX FAST FULL SCAN
select /*+index_ffs(a normal_empno_bmx)*/ a.empno from test_normal a select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID 9rgzkasky186v, child number 0 ------------------------------------- select /*+index_ffs(a normal_empno_bmx)*/ a.empno from test_normal a Plan hash value: 2075344169 ------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 3141 (100)| | | 1 | BITMAP CONVERSION TO ROWIDS | | 1000K| 4882K| 3141 (1)| 00:00:38 | | 2 | BITMAP INDEX FAST FULL SCAN| NORMAL_EMPNO_BMX | | | | | -------------------------------------------------------------------------------------------------
(六)、位图按位与: BITMAP AND、BITMAP OR
select * from test_normal where empno=3969 and sal in (1008,1011) select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID cyf5th2ts2z7j, child number 0 ------------------------------------- select * from test_normal where empno=3969 and sal in (1008,1011) Plan hash value: 640003492 -------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 5 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID | TEST_NORMAL | 1 | 40 | 5 (0)| 00:00:01 | | 2 | BITMAP CONVERSION TO ROWIDS | | | | | | | 3 | BITMAP AND | | | | | | | 4 | BITMAP OR | | | | | | |* 5 | BITMAP INDEX SINGLE VALUE| NORMAL_EMPNO_SAL | | | | | |* 6 | BITMAP INDEX SINGLE VALUE| NORMAL_EMPNO_SAL | | | | | |* 7 | BITMAP INDEX SINGLE VALUE | NORMAL_EMPNO_BMX | | | | | -------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 5 - access("SAL"=1008) 6 - access("SAL"=1011) 7 - access("EMPNO"=3969)
(七)、位图按位减: BITMAP MINUS
select /*+index_ffs(test_normal normal_empno_sal)*/ * from test_normal where empno>=50 and empno<=20000 and sal not in (1008) select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID dn3yq5vrp1524, child number 0 ------------------------------------- select /*+index_ffs(test_normal normal_empno_sal)*/ * from test_normal where empno>=50 and empno<=20000 and sal not in (1008) Plan hash value: 3977516083 -------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 1385 (100)| | | 1 | TABLE ACCESS BY INDEX ROWID | TEST_NORMAL | 19949 | 779K| 1385 (1)| 00:00:17 | | 2 | BITMAP CONVERSION TO ROWIDS | | | | | | | 3 | BITMAP MINUS | | | | | | | 4 | BITMAP MINUS | | | | | | | 5 | BITMAP MERGE | | | | | | |* 6 | BITMAP INDEX RANGE SCAN | NORMAL_EMPNO_BMX | | | | | |* 7 | BITMAP INDEX SINGLE VALUE| NORMAL_EMPNO_SAL | | | | | |* 8 | BITMAP INDEX SINGLE VALUE | NORMAL_EMPNO_SAL | | | | | -------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 6 - access("EMPNO">=50 AND "EMPNO"<=20000) 7 - access("SAL"=1008) 8 - access("SAL" IS NULL)
列值为NULL,位图索引是记录,以上这个例子中也把列为NULL剔除
四、表连接的访问方式
- 嵌套循环连接:NESTED LOOPS
- 哈希连接:hash join
- 排序合并连接:sort join和merge join
- 反连接:nested loops anti、hash join anti、merge join anti
- 半连接:nested loop semi、hash join semi、merge join semi
(一)、嵌套循环连接:NESTED LOOPS
select /*+leading(a) use_nl(b)*/* from scott.emp a , scott.dept b where a.deptno=b.deptno select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID c6xax626nhn8k, child number 0 ------------------------------------- select /*+leading(a) use_nl(b)*/* from scott.emp a , scott.dept b where a.deptno=b.deptno Plan hash value: 3625962092 ---------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 17 (100)| | | 1 | NESTED LOOPS | | | | | | | 2 | NESTED LOOPS | | 14 | 798 | 17 (0)| 00:00:01 | | 3 | TABLE ACCESS FULL | EMP | 14 | 532 | 3 (0)| 00:00:01 | |* 4 | INDEX UNIQUE SCAN | PK_DEPT | 1 | | 0 (0)| | | 5 | TABLE ACCESS BY INDEX ROWID| DEPT | 1 | 19 | 1 (0)| 00:00:01 | ---------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - access("A"."DEPTNO"="B"."DEPTNO")
(二)、哈希连接:hash join
select /*+leading(a) use_hash(b)*/* from scott.emp a , scott.dept b where a.deptno=b.deptno select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID fq65sryy1d9dw, child number 0 ------------------------------------- select /*+leading(a) use_hash(b)*/* from scott.emp a , scott.dept b where a.deptno=b.deptno Plan hash value: 1123238657 --------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 7 (100)| | |* 1 | HASH JOIN | | 14 | 798 | 7 (15)| 00:00:01 | | 2 | TABLE ACCESS FULL| EMP | 14 | 532 | 3 (0)| 00:00:01 | | 3 | TABLE ACCESS FULL| DEPT | 3 | 57 | 3 (0)| 00:00:01 | --------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("A"."DEPTNO"="B"."DEPTNO")
(三)、排序合并连接:sort join和merge join
select /*+use_merge(a b)*/* from scott.emp a , scott.dept b where a.deptno=b.deptno select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID 9w06suya2pdrn, child number 0 ------------------------------------- select /*+use_merge(a b)*/* from scott.emp a , scott.dept b where a.deptno=b.deptno Plan hash value: 844388907 ---------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 6 (100)| | | 1 | MERGE JOIN | | 14 | 798 | 6 (17)| 00:00:01 | | 2 | TABLE ACCESS BY INDEX ROWID| DEPT | 3 | 57 | 2 (0)| 00:00:01 | | 3 | INDEX FULL SCAN | PK_DEPT | 3 | | 1 (0)| 00:00:01 | |* 4 | SORT JOIN | | 14 | 532 | 4 (25)| 00:00:01 | | 5 | TABLE ACCESS FULL | EMP | 14 | 532 | 3 (0)| 00:00:01 | ---------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - access("A"."DEPTNO"="B"."DEPTNO") filter("A"."DEPTNO"="B"."DEPTNO")
(四)、反连接:nested loops anti
alter table scott.emp modify(deptno not null) select * from scott.emp a WHERE A.DEPTNO NOT IN (SELECT /*+nl_aj*/ DEPTNO FROM scott.dept b where a.deptno=b.deptno) select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID dh1c9mwpw9pjx, child number 0 ------------------------------------- select * from scott.emp a WHERE A.DEPTNO NOT IN (SELECT /*+nl_aj*/ DEPTNO FROM scott.dept b where a.deptno=b.deptno) Plan hash value: 3496123964 ------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | | | 3 (100)| | | 1 | NESTED LOOPS ANTI | | 7 | 287 | 3 (0)| 00:00:01 | | 2 | TABLE ACCESS FULL| EMP | 14 | 532 | 3 (0)| 00:00:01 | |* 3 | INDEX UNIQUE SCAN| PK_DEPT | 2 | 6 | 0 (0)| | ------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("A"."DEPTNO"="B"."DEPTNO")
(五)、反连接:hash join anti
select * from scott.emp a WHERE A.DEPTNO NOT IN (SELECT /*+hash_aj*/ DEPTNO FROM scott.dept b where a.deptno=b.deptno) select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID dhq4hhqgqqn0n, child number 0 ------------------------------------- select * from scott.emp a WHERE A.DEPTNO NOT IN (SELECT /*+hash_aj*/ DEPTNO FROM scott.dept b where a.deptno=b.deptno) Plan hash value: 1958379418 ------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | | | 5 (100)| | |* 1 | HASH JOIN ANTI | | 7 | 287 | 5 (20)| 00:00:01 | | 2 | TABLE ACCESS FULL| EMP | 14 | 532 | 3 (0)| 00:00:01 | | 3 | INDEX FULL SCAN | PK_DEPT | 3 | 9 | 1 (0)| 00:00:01 | ------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("A"."DEPTNO"="B"."DEPTNO")
(六)、反连接:merge join anti
select * from scott.emp a WHERE A.DEPTNO NOT IN (SELECT /*+merge_aj*/ DEPTNO FROM scott.dept b where a.deptno=b.deptno) select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID 1r60ktudp9vq2, child number 0 ------------------------------------- select * from scott.emp a WHERE A.DEPTNO NOT IN (SELECT /*+merge_aj*/ DEPTNO FROM scott.dept b where a.deptno=b.deptno) Plan hash value: 4267419248 ------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 6 (100)| | | 1 | MERGE JOIN ANTI | | 7 | 287 | 6 (34)| 00:00:01 | | 2 | SORT JOIN | | 14 | 532 | 4 (25)| 00:00:01 | | 3 | TABLE ACCESS FULL| EMP | 14 | 532 | 3 (0)| 00:00:01 | |* 4 | SORT UNIQUE | | 3 | 9 | 2 (50)| 00:00:01 | | 5 | INDEX FULL SCAN | PK_DEPT | 3 | 9 | 1 (0)| 00:00:01 | ------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - access("A"."DEPTNO"="B"."DEPTNO") filter("A"."DEPTNO"="B"."DEPTNO")
(七)、半连接:nested loop semi
select * from scott.emp a WHERE EXISTS (SELECT /*+nl_sj*/ 1 FROM scott.dept b where a.deptno=b.deptno) select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID 9htytj0pxjhkg, child number 0 ------------------------------------- select * from scott.emp a WHERE EXISTS (SELECT /*+nl_sj*/ 1 FROM scott.dept b where a.deptno=b.deptno) Plan hash value: 3274513678 ------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | | | 3 (100)| | | 1 | NESTED LOOPS SEMI | | 7 | 287 | 3 (0)| 00:00:01 | | 2 | TABLE ACCESS FULL| EMP | 14 | 532 | 3 (0)| 00:00:01 | |* 3 | INDEX UNIQUE SCAN| PK_DEPT | 2 | 6 | 0 (0)| | ------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("A"."DEPTNO"="B"."DEPTNO")
(八)、半连接:hash join semi
select * from scott.emp a WHERE EXISTS (SELECT /*+hash_sj*/ 1 FROM scott.dept b where a.deptno=b.deptno) select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID cjhjgkgs8q1fc, child number 0 ------------------------------------- select * from scott.emp a WHERE EXISTS (SELECT /*+hash_sj*/ 1 FROM scott.dept b where a.deptno=b.deptno) Plan hash value: 3753861400 ------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | | | 5 (100)| | |* 1 | HASH JOIN SEMI | | 7 | 287 | 5 (20)| 00:00:01 | | 2 | TABLE ACCESS FULL| EMP | 14 | 532 | 3 (0)| 00:00:01 | | 3 | INDEX FULL SCAN | PK_DEPT | 3 | 9 | 1 (0)| 00:00:01 | ------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("A"."DEPTNO"="B"."DEPTNO")
(九)、半连接:merge join semi
select * from scott.emp a WHERE EXISTS (SELECT /*+merge_sj*/ 1 FROM scott.dept b where a.deptno=b.deptno) select *from table(dbms_xplan.display_cursor(null,null)) SQL_ID f2zxcjpqvpsu5, child number 0 ------------------------------------- select * from scott.emp a WHERE EXISTS (SELECT /*+merge_sj*/ 1 FROM scott.dept b where a.deptno=b.deptno) Plan hash value: 3011744318 ------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 6 (100)| | | 1 | MERGE JOIN SEMI | | 7 | 287 | 6 (34)| 00:00:01 | | 2 | SORT JOIN | | 14 | 532 | 4 (25)| 00:00:01 | | 3 | TABLE ACCESS FULL| EMP | 14 | 532 | 3 (0)| 00:00:01 | |* 4 | SORT UNIQUE | | 3 | 9 | 2 (50)| 00:00:01 | | 5 | INDEX FULL SCAN | PK_DEPT | 3 | 9 | 1 (0)| 00:00:01 | ------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - access("A"."DEPTNO"="B"."DEPTNO") filter("A"."DEPTNO"="B"."DEPTNO")
时间: 2024-10-10 07:09:01