分区、内存-深入理解Oracle表(5):三大表连接方式详解之Hash Join的定义,原-by小雨

文章结束给大家来个程序员笑话:[M]

    Hash Join只能用于相称接连,且只能在CBO优化器模式下。于对相nested loop join,hash join更适合理处大型结果集
        Hash Join的执行计划第1个是hash表(build table),第2个探表查(probe table),一般不叫内表面,nested loop才有内表面
        Hash表也就是所谓的内表,探表查所谓的表面
        两者的执行计划形如:
        nested loop
            outer table             --动驱表
            inner table
       
       hash join
           build table              (inner table) --动驱表
 
            probe table             (outer  table)
         先看一张图片,大致懂得Hash Join的程过:
         

 

 

         上面细详懂得一下Hash Join
 
         ㈠ Hash join念概
          
          [color=ize:24px]Hash join算法的一个基本思想就是根据小的row sources(称作build input 也就是前文提到的build table,我们记小较的表为S,大较的表为B)
           立建一个可以存在于hash area内存中的hash table
           然后用大的row sources(称作probe input,也就是前文提到的probe table) 来测探面前所建的hash table
           如果hash area内存不够大,hash table就没法全完放存在hash area内存中
           针对这类情况,Oracle在接连键利用一个hash函数将build input和probe input分割成多个不相连的分区
           别分记作Si和Bi,这个阶段叫做分区阶段;然后各自响应的分区,即Si和Bi再做Hash join,这个阶段叫做join阶段
          如果HASH表太大,没法一次结构在内存中,则成分若干个partition,写入磁盘的temporary segment,则会多一个写的价代,会低降效率
           至于小表的念概,对于 hash join 说来,能包容在 pga 中的 hash table 都可以叫小表,平日比如:
           pga_aggregate_target                 big integer    1073741824
           hash  area size 大体能用使到40多 M ,这样的话平日可能包容 几十万的记载
           hash area size省缺是2*sort_area_size,我们可以直接改修SORT_AREA_SIZE 的巨细,HASH_AREA_SIZE也会着跟变改的
           如果你的workarea_size_policy=auto,那么我们需只设定pga_aggregate_target
           但请记着,这是一个session级别的参数,偶然,我们更倾向于把hash_area_size的巨细设成动驱表的1.6倍右左
           动驱表仅仅用于nested loop join 和 hash join,但Hash join不须要在动驱表上存在索引,而nested loop join则急切需求
           一两百万记载的表 join上  千万记载的表,hash join的平日现表非常好
           不过,多与少,大与小,很多时候很难化量,具体情况还得具体分析
           如果在分区后,针对某个分区所建的hash table还是太大的话,oracle就用采nested loop hash join
           所谓的nested-loops hash join就是对分部Si立建hash table,然后读取全体的Bi与所建的hash table做接连
           然后再对残余的Si立建hash table,再将全体的Bi与所建的hash table做接连,直至全体的Si都接连完了
       
       ㈡ Hash Join道理
       
          [color=ize:24px]斟酌以下两个据数集:
           S={1,1,1,3,3,4,4,4,4,5,8,8,8,8,10}
           B={0,0,1,1,1,1,2,2,2,2,2,2,3,8,9,9,9,10,10,11}
           Hash Join的第一步就是判断小表(即build input)否是能全完放存在hash area内存中
           如果能全完放存在内存中,则在内存中立建hash table,这是最简略的hash join
           如果不能全体放存在内存中,则build input必须分区。分区的个数叫做fan-out
           Fan-out是由hash_area_size和cluster size来决议的。其中cluster size于等db_block_size * _hash_multiblock_io_count
           hash_multiblock_io_count是个隐藏参数,在9.0.1当前就不再用使了
 
  sys@ORCL> ed
 Wrote file afiedt.buf
 
  1  select a.ksppinm name,b.ksppstvl value,a.ksppdesc description
   2  from x$ksppi a,x$ksppcv b
   3  where a.indx = b.indx
   4* and a.ksppinm like '%hash_multiblock_io_count%'
 sys@ORCL> /
 
NAME                           VALUE DESCRIPTION
 ------------------------------ ----- ------------------------------------------------------------
 _hash_multiblock_io_count      0     number of blocks hash join will read/write at once
           Oracle用采外部一个hash函数作用于接连键上,将S和B分割成多个分区
           在这里我们假设这个hash函数为求余函数,即Mod(join_column_value,10)
           这样生产十个分区,如下表:
 
 
             

 

 

            经过这样的分区以后,只须要响应的分区之间做join可即(也就是所谓的partition pairs) 
           如果有一个分区为NULL的话,则响应的分区join可即略忽
           在将S表读入内存分区时,oracle即记载接连键的独一值,构建成所谓的位图向量
           它须要占hash area内存的5%右左。在这里即为{1,3,4,5,8,10}
           当对B表停止分区时,将个一每接连键上的值与位图向量相较比,如果不在其中,则将其记载弃丢
           在我们这个例子中,B表中以下据数将被弃丢{0,0,2,2,2,2,2,2,9,9,9,9,9}
           这个程过就是位图向量过滤
           当S1,B1做完接连后,接着对Si,Bi停止接连
           这里oracle将较比两个分区,选取小的那个做build input,就是态动角色换互
           这个态动角色换互产生在除第一对分区之外的分区面上
 
 
 
         ㈢ Hash Join算法
       
          [color=ize:24px]第1步:判断小表否是够能全体放存在hash area内存中,如果可以,则做内存hash join。如果行不,转第二步
           第2步:决议fan-out数
                        (Number of Partitions) * C<= Favm *M
                       其中C为Cluster size,其值为DB_BLOCK_SIZE*HASH_MULTIBLOCK_IO_COUNT
                       Favm为hash area内存可以用使的百分比,一般为0.8右左
                       M为Hash_area_size的巨细
           第3步:读取分部小表S,用采外部hash函数(这里称为hash_fun_1)
                        将接连键值映射至某个分区,同时用采hash_fun_2函数对接连键值生产另外一个hash值
                        这个hash值用于创立hash table用,并且与接连键值放存在起一
           第4步:对build input立建位图向量
           第5步:如果内存中没有空间了,则将分区写至磁盘上
           第6步:读取小表S的残余分部,重复第三步,直至小表S全体读完
           第7步:将分区按巨细排序,选取几个分区立建hash table(这里选取分区的原则是使选取的数量最多)
           第8步:根据面前用hash_fun_2函数算计好的hash值,立建hash table
           第9步:读取表B,用采位图向量停止位图向量过滤
           第10步:对通过过滤的据数用采hash_fun_1函数将据数映射到响应的分区中去,并算计hash_fun_2的hash值
           第11步:如果所落的分区在内存中,则将面前通过hash_fun_2函数算计所得的hash值与内存中已存在的hash table做接连
                          将结果写致磁盘上。如果所落的分区不在内存中,则将响应的值与表S响应的分区放在起一
           第12步:续继读取表B,重复第9步,直至表B读取终了 
           第13步:读取响应的(Si,Bi)做hash接连。在这里会产生态动角色换互
           第14步:如果分区后过,小最的分区也比内存大,则产生nested-loop hash join  
  
     
        ㈣ Hash Join的本成
       
          ⑴ In-Memory Hash Join
               Cost(HJ)=Read(S)+ build hash table in memory(CPU)+Read(B) + Perform In memory Join(CPU)
               略忽cpu的时光,则:
               Cost(HJ)=Read(S)+Read(B)
             
          ⑵ On-Disk Hash Join
               根据上述的骤步述描,我们可以看出:
               Cost(HJ)=Cost(HJ1)+Cost(HJ2) 
               其中Cost(HJ1)的本成就是扫描S,B表,并将没法放在内存上的分部写回磁盘,对应面前第2步至第12步
                      Cost(HJ2)即为做nested-loop hash join的本成,对应面前的第13步至第14步
               其中Cost(HJ1)近似于等Read(S)+Read(B)+Write((S-M)+(B-B*M/S))
               因为在做nested-loop hash join时,对每一chunk的build input,都须要读取整个probe input,因此
               Cost(HJ2)近似于等Read((S-M)+n*(B-B*M/S)),其中n是nested-loop hash join须要循环的次数:n=(S/F)/M
               一般情况下,如果n大于10的话,hash join的能性将大大下落
               从n的算计公式可以看出,n与Fan-out成反比例,高提fan-out,可以低降n
               当hash_area_size是固准时,可以低降cluster size来高提fan-out
               从这里我们可以看出,高提hash_multiblock_io_count参数的值并不一定高提hash join的能性
  
             
       ㈤ Hash Join的程过
       
          [color=ize:24px]一次完全的hash join如下:
           1  算计小表的分区(bucket)数--Hash分桶
               决议hash join的一个重要因素是小表的分区(bucket)数
               这个字数由hash_area_size、hash_multiblock_io_count和db_block_size参数独特决议
               Oracle会留保hash

    游戏开辟论坛:http://jiushun8.com/forum.php?mod=viewthread&tid=5546&extra=page%3D1

文章结束给大家分享下程序员的一些笑话语录: 手机终究会变成PC,所以ip会比wm更加畅销,但是有一天手机强大到一定程度了就会发现只有wm的支持才能完美享受。就好比树和草,草长得再高也是草,时间到了条件成熟了树就会窜天高了。www.ishuo.cn

posted @ 2013-04-18 17:14  坚固66  阅读(390)  评论(0编辑  收藏  举报