网站建设资讯

NEWS

网站建设资讯

oracle怎么走哈希 oracle 哈希连接

oracle什么时候选择hash join算法

Hash Join只能用于相等连接,且只能在CBO优化器模式下。相对于nested loop join,hash join更适合处理大型结果集Hash Join的执行计划第1个是hash表(build table),第2个探查表(probe table),一般不叫内外表,nested loop才有内外表Hash表也就是所谓的内表,探查表所谓的外表

创新互联公司-专业网站定制、快速模板网站建设、高性价比青龙网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式青龙网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖青龙地区。费用合理售后完善,十载实体公司更值得信赖。

两者的执行计划形如:

nested loop

outer table --驱动表

inner table

hash join

build table (inner table) --驱动表

probe table (outer table)

先看一张图片,大致了解Hash Join的过程:

深入理解Oracle表:三大表连接方式详解之Hash Join的定义,原理,算法,成本,模式和位图 - Andy - Andys home下面详细了解一下Hash Join

一 Hash join概念

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 1073741824hash 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原理

考虑以下两个数据集:

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-outFan-out是由hash_area_size和cluster size来决定的。其中cluster size等于db_block_size * _hash_multiblock_io_counthash_multiblock_io_count是个隐藏参数,在9.0.1以后就不再使用了[sql]

sys@ORCL ed

Wrote file afiedt.buf

1 select a.ksppinm name,b.ksppstvl value,a.ksppdesc description2 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 onceOracle采用内部一个hash函数作用于连接键上,将S和B分割成多个分区在这里我们假设这个hash函数为求余函数,即Mod(join_column_value,10)这样产生十个分区,如下表:

深入理解Oracle表:三大表连接方式详解之Hash Join的定义,原理,算法,成本,模式和位图 - Andy - Andys home经过这样的分区之后,只需要相应的分区之间做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算法

第1步:判定小表是否能够全部存放在hash area内存中,如果可以,则做内存hash join。如果不行,转第二步第2步:决定fan-out数

(Number of Partitions) * C= Favm *M

其中C为Cluster size,其值为DB_BLOCK_SIZE*HASH_MULTIBLOCK_IO_COUNTFavm为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的过程

一次完整的hash join如下:

1 计算小表的分区(bucket)数--Hash分桶

决定hash join的一个重要因素是小表的分区(bucket)数这个数字由hash_area_size、hash_multiblock_io_count和db_block_size参数共同决定Oracle会保留hash area的20%来存储分区的头信息、hash位图信息和hash表因此,这个数字的计算公式是:

Bucket数=0.8*hash_area_size/(hash_multiblock_io_count*db_block_size)2 Hash计算

读取小表数据(简称为R),并对每一条数据根据hash算法进行计算Oracle采用两种hash算法进行计算,计算出能达到最快速度的hash值(第一hash值和第二hash值)而关于这些分区的全部hash值(第一hash值)就成为hash表3 存放数据到hash内存中

将经过hash算法计算的数据,根据各个bucket的hash值(第一hash值)分别放入相应的bucket中第二hash值就存放在各条记录中

4 创建hash位图

与此同时,也创建了一个关于这两个hash值映射关系的hash位图5 超出内存大小部分被移到磁盘

如果hash area被占满,那最大一个分区就会被写到磁盘(临时表空间)上去任何需要写入到磁盘分区上的记录都会导致磁盘分区被更新这样的话,就会严重影响性能,因此一定要尽量避免这种情况2-5一直持续到整个表的数据读取完毕

6 对分区排序

为了能充分利用内存,尽量存储更多的分区,Oracle会按照各个分区的大小将他们在内存中排序7 读取大表数据,进行hash匹配

接下来就开始读取大表(简称S)中的数据

按顺序每读取一条记录,计算它的hash值,并检查是否与内存中的分区的hash值一致如果是,返回join数据

如果内存中的分区没有符合的,就将S中的数据写入到一个新的分区中,这个分区也采用与计算R一样的算法计算出hash值也就是说这些S中的数据产生的新的分区数应该和R的分区集的分区数一样。这些新的分区被存储在磁盘(临时表空间)上8 完全大表全部数据的读取

一直按照7进行,直到大表中的所有数据的读取完毕9 处理没有join的数据

这个时候就产生了一大堆join好的数据和从R和S中计算存储在磁盘上的分区10 二次hash计算

从R和S的分区集中抽取出最小的一个分区,使用第二种hash函数计算出并在内存中创建hash表采用第二种hash函数的原因是为了使数据分布性更好11 二次hash匹配

在从另一个数据源(与hash在内存的那个分区所属数据源不同的)中读取分区数据,与内存中的新hash表进行匹配。返回join数据12 完成全部hash join

继续按照9-11处理剩余分区,直到全部处理完毕六 Hash Join的模式

Oracle中,Hash Join也有三种模式:optimal,one-pass,multi-pass⑴ optimal

当驱动结果集生成的hash表全部可以放入PGA的hash area时,称为optimal,大致过程如下:

① 先根据驱动表,得到驱动结果集

② 在hash area生成hash bulket,并将若干bulket分成一组,成为一个partition,还会生成一个bitmap的列表,每个bulket在上面占一位③ 对结果集的join键做hash运算,将数据分散到相应partition的bulket中当运算完成后,如果键值唯一性较高的话,bulket里的数据会比较均匀,也有可能有的桶里面数据会是空的这样bitmap上对应的标志位就是0,有数据的桶,标志位会是1④ 开始扫描第二张表,对jion键做hash运算,确定应该到某个partition的某个bulket去探测探测之前,会看这个bulket的bitmap是否会1,如果为0,表示没数据,这行就直接丢弃掉⑤ 如果bitmap为1,则在桶内做精确匹配,判断OK后,返回数据这个是最优的hash join,他的成本基本是两张表的full table scan,在加微量的hash运算博客开篇的那幅图描述的也就是这种情况

⑵ one-pass

如果进程的pga很小,或者驱动表结果集很大,超过了hash area的大小,会怎么办?

当然会用到临时表空间,此时oracle的处理方式稍微复杂点需奥注意上面提到的有个partition的概念可以这么理解,数据是经过两次hash运算的,先确定你的partition,再确定你的bulket假设hash area小于整个hash table,但至少大于一个partition的size,这个时候走的就是one-pass当我们生成好hash表后,状况是部分partition留在内存中,其他的partition留在磁盘临时表空间中当然也有可能某个partition一半在内存,一半在磁盘,剩下的步骤大致如下:

① 扫描第二张表,对join键做hash运算,确定好对应的partition和bulket② 查看bitmap,确定bulket是否有数据,没有则直接丢弃③ 如果有数据,并且这个partition是在内存中的,就进入对应的桶去精确匹配,能匹配上,就返回这行数据,否则丢弃④ 如果partition是在磁盘上的,则将这行数据放入磁盘中暂存起来,保存的形式也是partition,bulket的方式⑤ 当第二张表被扫描完后,剩下的是驱动表和探测表生成的一大堆partition,保留在磁盘上⑥ 由于两边的数据都按照相同的hash算法做了partition和bulket,现在只要成对的比较两边partition数据即可并且在比较的时候,oracle也做了优化处理,没有严格的驱动与被驱动关系他会在partition对中选较小的一个作为驱动来进行,直到磁盘上所有的partition对都join完可以发现,相比optimal,他多出的成本是对于无法放入内存的partition,重新读取了一次,所以称为one-pass只要你的内存保证能装下一个partition,oracle都会腾挪空间,每个磁盘partition做到one-pass⑶ multi-pass

这是最复杂,最糟糕的hash join

此时hash area小到连一个partition也容纳不下,当扫描好驱动表后可能只有半个partition留在hash area中,另半个加其他的partition全在磁盘上剩下的步骤和one-pass比价类似,不同的是针对partition的处理由于驱动表只有半个partition在内存中,探测表对应的partition数据做探测时如果匹配不上,这行还不能直接丢弃,需要继续保留到磁盘,和驱动表剩下的半个partition再做join这里举例的是内存可以装下半个partition,如果装的更少的话,反复join的次数将更多当发生multi-pass时,partition物理读的次数会显著增加七 Hash Join的位图

这个位图包含了每个hash分区是否有有值的信息。它记录了有数据的分区的hash值这个位图的最大作用就是,如果probe input中的数据没有与内存中的hash表匹配上先查看这个位图,以决定是否将没有匹配的数据写入磁盘那些不可能匹配到的数据(即位图上对应的分区没有数据)就不再写入磁盘八 小结

① 确认小表是驱动表

② 确认涉及到的表和连接键分析过了

③ 如果在连接键上数据不均匀的话,建议做柱状图④ 如果可以,调大hash_area_size的大小或pga_aggregate_target的值⑤ Hash Join适合于小表与大表连接、返回大型结果集的连接

oracle 怎么使用哈希链接

对于排序合并连接,如果两个表在施加了目标SQL中指定的谓词条件后得到的结果集很大而且需要排序,则排序合并连接的执行效率一定不高;

而对于嵌套循环连接,如果驱动表所对应的驱动结果集的记录数很大,即便在被驱动表的连接列上存在索引,此时使用嵌套循环连接的执行效率也会同样不高。

为了解决这个问题,于是Oracle引进了哈希连接。在ORACLE 10g及其以后的版本中,优化器 (实际上是CBO,因为哈希连接仅适用于CBO)在解析目标SQL的时候是否考虑哈希连接受限于隐含参数_HASH_JOIN_ENABLED,默认值是TRUE.

oracle hash join 怎么用

hash join是一种连接方式,一般用在等值连接,oracle会根据具体的成本选择是否使用这种连接方式。如果一定要使用hash join可以家hint使用,具体的hint写法忘记了,自己查查吧。好象是/*+hash+*/

如果大表和小表的连接,一般会用nested loop连接方式。自查询的in等连接方式一般也是这种选择方式。

oracle的执行计划中表的链接方式有几种?分别适用什么情况?

在日常基于数据库应用的开发过程中,我们经常需要对多个表或者数据源进行关联查询而得出我们需要的结果集。那么Oracle到底存在着哪几种连接方式?优化器内部又是怎样处理这些连接的?哪种连接方式又是适合哪种查询需求的?只有对这些问题有了清晰的理解后,我们才能针对特定的查询需求选择合适的连接方式,开发出健壮的数据库应用程序。选择合适的表连接方法对SQL语句运行的性能有着至关重要的影响。下面我们就Oracle常用的一些连接方法及适用情景做一个简单的介绍。

3.1 嵌套循环连接(nested loop)

嵌套循环连接的工作方式是这样的:

1、 Oracle首先选择一张表作为连接的驱动表,这张表也称为外部表(Outer Table)。由驱动表进行驱动连接的表或数据源称为内部表(Inner Table)。

2、 提取驱动表中符合条件的记录,与被驱动表的连接列进行关联查询符合条件的记录。在这个过程中,Oracle首先提取驱动表中符合条件的第一条记录,再与内部表的连接列进行关联查询相应的记录行。在关联查询的过程中,Oracle会持续提取驱动表中其他符合条件的记录与内部表关联查询。这两个过程是并行进行的,因此嵌套循环连接返回前几条记录的速度是非常快的。在这里需要说明的是,由于Oracle最小的IO单位为单个数据块,因此在这个过程中Oracle会首先提取驱动表中符合条件的单个数据块中的所有行,再与内部表进行关联连接查询的,然后提取下一个数据块中的记录持续地循环连接下去。当然,如果单行记录跨越多个数据块的话,就是一次单条记录进行关联查询的。

3、 嵌套循环连接的过程如下所示:

Nested loop

Outer loop

Inner loop

我们可以看出这里面存在着两个循环,一个是外部循环,提取驱动表中符合条件的每条记录。另外一个是内部循环,根据外循环中提取的每条记录对内部表进行连接查询相应的记录。由于这两个循环是嵌套进行的,故此种连接方法称为嵌套循环连接。

嵌套循环连接适用于查询的选择性强、约束性高并且仅返回小部分记录的结果集。通常要求驱动表的记录(符合条件的记录,通常通过高效的索引访问)较少,且被驱动表连接列有唯一索引或者选择性强的非唯一索引时,嵌套循环连接的效率是比较高的。

嵌套循环连接驱动表的选择也是连接中需要着重注意的一点,有一个常见的误区是驱动表要选择小表,其实这是不对的。假如有两张表A、B关联查询,A表有1000000条记录,B表有10000条记录,但是A表过滤出来的记录只有10条,这时候显然用A表当做驱动表是比较合适的。因此驱动表是由过滤条件限制返回记录最少的那张表,而不是根据表的大小来选择的。

在外连接查询中,如果走嵌套循环连接的话,那么驱动表必然是没有符合条件关联的那张表,也就是后面不加(+)的那张表。这是由于外连接需要提取可能另一张表没符合条件的记录,因此驱动表需要是那张我们要返回所有符合条件记录的表。比如下面这个查询,

嵌套循环连接返回前几行的记录是非常快的,这是因为使用了嵌套循环后,不需要等到全部循环结束再返回结果集,而是不断地将查询出来的结果集返回。在这种情况下,终端用户将会快速地得到返回的首批记录,且同时等待Oracle内部处理其他记录并返回。如果查询的驱动表的记录数非常多,或者被驱动表的连接列上无索引或索引不是高度可选的情况,嵌套循环连接的效率是非常低的

-- 删除原表

drop table t1;

-- 建立测试表

create table t1(

f1 varchar2(10),

f2 varchar2(1000)

)

tablespace CTL

pctfree 98;

-- 填充测试内容

insert into t1(f1,f2)

select rownum, lpad(rownum,700,'0')

from dba_tables a, dba_tab_cols b

where a.owner = b.owner

and rownum 10000;

commit;

-- 检查测试内容格式

select sys.dbms_rowid.rowid_block_number(rowid), f1, f2 from t1;

-- 每条记录都存储在单独的数据块中

select count( distinct sys.dbms_rowid.rowid_block_number(rowid)) from t1;

/*

用同样的方式建立表t2

*/

-- 删除原表

drop table t2;

-- 建立测试表

create table t2(

f1 varchar2(10),

f2 varchar2(1000)

)

tablespace CTL

pctfree 98;

-- 填充测试内容

insert into t2(f1,f2)

select rownum * 10, lpad(rownum * 10,700,'0')

from dba_tables a, dba_tab_cols b

where a.owner = b.owner

and rownum 1000;

commit;

-- 检查测试内容格式

select sys.dbms_rowid.rowid_block_number(rowid), f1, f2 from t2;

-- 每条记录都存储在单独的数据块中

select count( distinct sys.dbms_rowid.rowid_block_number(rowid)) from t2;

create index ind_t1_f1 on t1(f1);

create index ind_t2_f1 on t2(f1);

--首先我们来看使用nested loop关联方式, 不同表作为驱动时的情况.

1, 表t2作为驱动表

select /*+ ordered use_nl(t1 , t2)*/

t1.f1, t2.f1

from ctl.t2 t2,ctl.t1 t1

where t1.f1 = t2.f1

and t1.f1 1000;

Execution Plan

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

0 SELECT STATEMENT Optimizer=CHOOSE (Cost=84 Card=4 Bytes=56)

1 0 NESTED LOOPS (Cost=84 Card=4 Bytes=56)

2 1 TABLE ACCESS (FULL) OF 'T2' (Cost=2 Card=82 Bytes=574)

3 1 INDEX (RANGE SCAN) OF 'IND_T1_F1' (NON-UNIQUE) (Cost=1 C

ard=1 Bytes=7)

Cost = outer access cost + (inner access cost * outer cardinality)

Cost = 2 + 1 * 82 = 84;

Statistics

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

0 recursive calls

0 db block gets

2020 consistent gets

23 physical reads

0 redo size

2650 bytes sent via SQL*Net to client

721 bytes received via SQL*Net from client

8 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

99 rows processed

2, t1作为驱动表

Execution Plan

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

0 SELECT STATEMENT Optimizer=CHOOSE (Cost=6 Card=4 Bytes=56)

1 0 NESTED LOOPS (Cost=6 Card=4 Bytes=56)

2 1 TABLE ACCESS (FULL) OF 'T1' (Cost=2 Card=4 Bytes=28)

3 1 INDEX (RANGE SCAN) OF 'IND_T2_F1' (NON-UNIQUE) (Cost=1 C

ard=1 Bytes=7)

Cost = outer access cost + (inner access cost * outer cardinality)

Cost = 2 + 1 * 4 = 84;

Statistics

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

0 recursive calls

0 db block gets

11123 consistent gets

3 physical reads

0 redo size

2650 bytes sent via SQL*Net to client

721 bytes received via SQL*Net from client

8 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

99 rows processed

3.2, 哈希连接(hash join)

哈希连接分为两个阶段,如下。

1、 构建阶段:优化器首先选择一张小表做为驱动表,运用哈希函数对连接列进行计算产生一张哈希表。通常这个步骤是在内存(hash_area_size)里面进行的,因此运算很快。

2、 探测阶段:优化器对被驱动表的连接列运用同样的哈希函数计算得到的结果与前面形成的哈希表进行探测返回符合条件的记录。这个阶段中如果被驱动表的连接列的值没有与驱动表连接列的值相等的话,那么这些记录将会被丢弃而不进行探测

哈希连接比较适用于返回大数据量结果集的连接。

使用哈希连接必须是在CBO模式下,参数hash_join_enabled设置为true,

哈希连接只适用于等值连接。从Oracle9i开始,哈希连接由于其良好的性能渐渐取代了原来的排序合并连接。

SQL select /*+ ordered use_hash(t1 , t2) */

t1.f1, t2.f1

from ctl.t1 t1,ctl.t2 t2

where t1.f1 = t2.f1 2 3 4 ;

999 rows selected.

Execution Plan

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

0 SELECT STATEMENT Optimizer=CHOOSE (Cost=5 Card=82 Bytes=1148

)

1 0 HASH JOIN (Cost=5 Card=82 Bytes=1148)

2 1 TABLE ACCESS (FULL) OF 'T1' (Cost=2 Card=82 Bytes=574)

3 1 TABLE ACCESS (FULL) OF 'T2' (Cost=2 Card=82 Bytes=574)

Statistics

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

0 recursive calls

0 db block gets

11113 consistent gets

0 physical reads

0 redo size

23590 bytes sent via SQL*Net to client

1381 bytes received via SQL*Net from client

68 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

999 rows processed

3.3, 排序合并连接(merge join)

排序合并连接的方法非常简单。在排序合并连接中是没有驱动表的概念的,两个互相连接的表按连接列的值先排序,排序完后形成的结果集再互相进行合并连接提取符合条件的记录。相比嵌套循环连接,排序合并连接比较适用于返回大数据量的结果。

排序合并连接在数据表预先排序好的情况下效率是非常高的,也比较适用于非等值连接的情况,比如、=、=等情况下的连接(哈希连接只适用于等值连接)。由于Oracle中排序操作的开销是非常消耗资源的,当结果集很大时排序合并连接的性能很差,于是Oracle在7.3之后推出了新的连接方式——哈希连接。

1, rbo模式;

2, 不等于关联( = = )

3, hash_join_enabled = false;

4, 数据源已排序

oracle11g hash 分区 索引怎么用

oracle11g hash 分区 索引怎么用

Hash Global分区索引介绍

HASH-Partitioned Global索引是Oracle 10g开始提供的新特性。而在以前的版本中

,Oracle只支持Range-Partitioned Global索引。HASH-Partitioned Global索引的好处如下:

比Range-Partitioned Global索引易于实施。HASH-Partitioned Global索引是根据

索引字段值,通过Oracle内部的HASH算法自动均匀散列到定义的分区中。而

Range-Partitioned Global索引需要根据索引字段值的范围进行分区,因此实施和

维护的难度都大。


当前文章:oracle怎么走哈希 oracle 哈希连接
当前地址:http://njwzjz.com/article/hjcosg.html