嵌套join和HashJoin以及Hash索引

嵌套join和Hash Join

首先谈谈Join的方式,不同的数据库有不同的Join方式,比如Mysql就只支持嵌套Join, 而Oracle在默认情况下是嵌套Join,而在显示的语句下,或者是Join没有索引的情况下,就会使用HashJoin.


示例语句:

select a.xx,b.xxx from a, b where a.id=b.parentId  

有两个表a和b, 现在要通过a.id和b.parentId进行join.


在嵌套Join的情况下,假设两个表上都有索引:

首先拿出a表的一条记录,取得id的值, 用这个id值,通过索引找到b表中所有的parentId和这个id值的行数,并返回记录。接下来再拿出下一条记录,再取id,再去b找对应记录。



而Hash Join的情形:

首先把a表的id,全部拿出来,对所有id都取hash值,并保存在内存中。 然后B表,对所有记录,都拿出parentId做hash值,每做一个,就用这个hash值去内存中看是否有相同的值存在,如果有,那么就返回这条记录作为结果集的一部分。



由此可见,在正常情况下,有索引,嵌套的方式可以很快定位到b表的记录, 相比之下速度要比Hash Join要好。而没有索引的情况下,就需要对b表挨条扫,速度会很慢。 所以Oracle会在这种情况下切换到Hash Join的方式。


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

Hash索引

Hash索引是相对于其他类型的索引,如B-Tree索引而言的。 如果在a.id上建立Hash索引,那么他会对所有id算hash值,并把hash值和磁盘地址一起保存起来。 当要查id=34343的时候,  对34343进行hash转换,然后迅速找到磁盘地址,取到记


录。 而不是像BTree一样,一段一段地比较,然后定位。  速度要快很多。

但是它的弱点就很明显,只能查单条,不能查范围。 比如 a.id<34343, 那么他就只能扫描全表。











你可能感兴趣的:(hash)