Oracle半连接学习总结(四)

2014-11-24 13:31:22 · 作者: · 浏览: 3
te 1 0.00 0.00 0 0 0 0

Fetch 1 0.00 0.00 0 10 0 100

------- ------ -------- -------------------- ---------- ---------- ----------

total 3 0.00 0.00 0 10 0 100

将表table_1数据增加到50万条,执行计划与跟踪结果表明,in 与exists的写法一样的效率。

在9i中,in 与exists的写法在执行计划与跟踪结果结果是不一样的,认为

Select * from T1 where x in ( select y fromT2 )

select *

from t1, ( select distinct y from t2 ) t2

where t1.x = t2.y;

是很相近的。

而exists的写法

select * from t1 where exists ( select nullfrom t2 where y = x )

具有以下的逻辑过程

for x in ( select * from t1 )

loop

if ( exists ( select null from t2 where y = x.x )

then

OUTPUT THE RECORD

end if

end loop

这表明总会导致table_1执行全表扫描,并能使用table_2上的索引

It always results in a full scan of T1whereas the first query can make use of an index on T1(x).

如果( select afrom table_1)结果很大,而(select *from table_2很小),这时候在table_2(a)存在索引的话,使用exists是有效率的写法。

而如果(select * from table_1)是很小的结果集,则采用in是更好的方法。

如果(select *from table_1) 与(select *from table_2)都是很大的结果集合,要看其他的一些因素,如索引等。

半连接还有一种写法

select count(a.b)

from table_2 a, (select distinct a from table_1) b

where a.a=b.a

但是测试结果表明,无论数据呈现怎样的特征,这种写法在效率上都比不上in 或者exists

我们将table_1,table_2的位置颠倒一下,结果就更加清楚了

EXPLAIN PLAN FOR

select

a.a,a.b

from table_2a, (select distinct a from table_1) b

where a.a=b.a

SELECT * FROM TABLE(DBMS_XPLAN.display());

--------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1001 | 26026 | 509 (2)| 00:00:07 |

| 1 | VIEW | VM_NWVW_1 | 1001 | 26026 | 509 (2)| 00:00:07 |

| 2 | HASH UNIQUE | | 1001 | 27027 | 509 (2)| 00:00:07 |

|* 3 | HASH JOIN | | 1001 | 27027 | 508 (2)| 00:00:07 |

| 4 | INDEX FAST FULL SCAN| IDX_TAB2_A | 1001 | 3003 | 3 (0)| 00:00:01 |

| 5 | TABLE ACCESS FULL |TABLE_1 | 500K| 11M| 502 (1)| 00:00:07 |

--------------------------------------------------------------------------------------

EXPLAIN PLAN FOR

select

a.a,a.b

from table_2 a

where a.a in (select a from table_1);

SELECT * FROM TABLE(DBMS_XPLAN.display());

------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1001 | 20020 | 313 (2)| 00:00:04 |

|* 1 | HASH JOIN SEMI | | 1001 | 20020 | 313 (2)| 00:00:04 |

| 2 | TABLE ACCESS FULL |TABLE_2 | 1001 | 16016 | 4 (0)| 00:00:01 |

| 3 | INDEX FAST FULL SCAN| IDX_TAB1_A | 500K| 1953K| 306 (1)| 00:00:04 |

------------------------------------------------------------------------------------

)

EXPLAIN PLAN FOR

select

a.a,a.b

from table_2 a

where exists (select null from table_1 b where a.a=b.a);

SELECT * FROM TABLE(DBMS_XPLAN.display());

----------------------------------------------------------------