表的连接方式 是执行计划生成的重要方面。
各种连接方式代表不同的连接操作算法。
不同的连接方式也适应不同的数据量和数据分布情况。
嵌套循环,随即读成本大,合并排序连接,需要大规模的sort操作,内存和temp空间压力大,在处理海量数据随机读,海量排序,都不能被接受。所以,hash Join连接比较常用。
Hash join 原理
Hash join是借助hash算法,连带小规模的nest loop join,同时利用内存空间进行高速数据缓存检索的一种算法。
Hash join算法步骤:
1) hash join连接对象依然是2个表,首先选择出其中一个小表,这里的小表,就是参与连接操作的数据集合数据量小。对连接列字段的所有数据值,进行hash 函数操作。Hash函数处理过得数据特征是‘相同数据值的hash函数值一定相同,不同数据值的hash函数值可能相同’;
2) 经过hash函数处理过的小表连接列,连同数据一起存在oracle PGA空间中,PGA中存在一块空间为hash_area,专门存放此类类型。并且,依据不同的hash函数值,进行划分bucket操作,每个bucket中包括所有相同hash函数值的小表数据,同时建立hash键值对应位图。
3) 之后对进行hash连接大表数据连接列依次读取,并将每个hash值进行bucket匹配,定位到适当的bucket上(应用hash检索算法)‘
4) 在定位到的bucket中,进行小规模的精确匹配,因为此时的范围已经缩小,进行匹配的成功率精确度高,同时,匹配是在内存中进行,速度较merge sort join快很多。
从原理过程来看,hash join 和 NL,一样,进行一定的嵌套循环匹配操作,不过差异在于匹配进行随机读的范围是受限范围。不会像NL直接频繁进行全表规模的随机读。
Hash join和 排序合并连接相似之处,都是利用PGA空间进行独立操作。Hashjoin的bucket就是保存在内存的PGA中,有一块专门hash_area进行该项操作。选择小表作为驱动表,就是尽量使PGA内存中可以完全装下小表,不使用temp表空间。这样hash匹配和精确匹配的速度就有保障。
最后,hash join使用场景是有限制的,最大的一个就是连接仅能使用等值‘=’连接。因为hash匹配的过程只能支持相等操作。还有就是连接列的数据分布要尽量做到均匀,这样产生的bucket也会比较均匀,这样匹配的速度才有保证。如果数据列分布偏移严重,hash join算法效率会有退化。
转自:
Oracle表连接操作——Hash Join(哈希连接)上
http://blog.itpub.net/17203031/viewspace-697442