zoukankan      html  css  js  c++  java
  • 分区、内存深入理解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

  • 相关阅读:
    研究显示:众多网上零售商未遵循Web优化基本准则
    坚果云开发团队分享高效代码审查经验
    不应忽视的HTML优化
    开源网络分析工具TCP Traffic Analyzer
    Web 2.0应用客户端性能问题十大根源
    W3C宣布成立Web性能工作组
    Google C++规范
    Yahoo推出开源YUI跨浏览器测试工具Yeti
    比较牛的一个字符画
    python调用windows下的应用程序的方法
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3029045.html
Copyright © 2011-2022 走看看