A表和B表,
A表有1百万条记录,B表有1千万条记录。
sql:select * from a where not exists(select * from b where b.code=a.code);当B表的code列上建有索引i_idx时,执行计划如下:
.......
hash join anti
table access full a ......
index fast full scan i_idx .....当B表的code列上无索引时,执行计划如下:
.......
hash join anti
table access full a ......
table access full b .....
我对exists的理解:
对外表a的每条记录进行扫描,每扫描一条记录后,就执行一次对内表B的查询(即:select * from b where b.code=a.code),
这样就类似一个循环,每循环1下,就执行1下对内表B的查询(即:select * from b where b.code=a.code),
这样的话表连接应是嵌套循环连接。问题:
1、我的理解对吗?
2、为什么执行计划里是hash join?而不是nested loops?
3、当我把not exists 改为exists 时,就看到hash join semi,请问anti与semi的区别 ?
A表有1百万条记录,B表有1千万条记录。
sql:select * from a where not exists(select * from b where b.code=a.code);当B表的code列上建有索引i_idx时,执行计划如下:
.......
hash join anti
table access full a ......
index fast full scan i_idx .....当B表的code列上无索引时,执行计划如下:
.......
hash join anti
table access full a ......
table access full b .....
我对exists的理解:
对外表a的每条记录进行扫描,每扫描一条记录后,就执行一次对内表B的查询(即:select * from b where b.code=a.code),
这样就类似一个循环,每循环1下,就执行1下对内表B的查询(即:select * from b where b.code=a.code),
这样的话表连接应是嵌套循环连接。问题:
1、我的理解对吗?
2、为什么执行计划里是hash join?而不是nested loops?
3、当我把not exists 改为exists 时,就看到hash join semi,请问anti与semi的区别 ?
Select * from T1 where x in ( select y from T2 )
LIKE:
select *
from t1, ( select distinct y from t2 ) t2
where t1.x = t2.y;
假如使用EXISTS,如同上述的查询结果,我们改写成:
select * from t1 where exists ( select null from t2 where y = x )
LIKE:
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
可以看看HASH JOIN原理
2. 一般来说对于返连接的表比较小,返回的数据集比如说少于1万,那么采用nest loop可能性能较好,相反,有成百上千万的记录,hash join效率较高。
3. hash join semi是针对类似exists的,如果在内层扫描中,命中就立即返回本轮匹配,而hash join anti则相反。
难道哈希连接也是个循环,每循环一次,
就执行1下对内表B的查询(即:select * from b where b.code=a.code)??
源)利用连接键在内存中建立散列表,然后扫描较大的表并探测散列表,找出与散列表匹配
的行