数据库常用的连接有如下三种:
1.hash join(哈希连接)
2.nested loop(嵌套连接)
3. merge join(合并连接)
连接原理概述
hash join原理概述
hash join是CBO 做大数据集连接时的常用方式。优化器扫描小表(或数据源),利用连接键(也就是根据连接字段计算hash 值)在内存中建立hash表,然后扫描大表,每读到一条记录就来探测hash表一次,找出与hash表匹配的行。当小表可以全部放入内存中,其成本接近全表扫描两个表的成本之和。如果表很大不能完全放入内存,这时优化器会将它分割成若干不同的分区,不能放入内存的部分就把该分区写入磁盘的临时段,此时要有较大的临时段从而尽量提高I/O 的性能。临时段中的分区都需要换进内存做hash join。这时候成本接近于全表扫描小表+分区数*全表扫描大表的代价和。至于两个表都进行分区,其好处是可以使用parallel query,就是多个进程同时对不同的分区进行join,然后再合并。但是复杂。
分析:
1.优化器根据统计信息,选择较小的表作为驱动表
2.在内存中建立基于连接键的哈希表
3.将大表的数据逐行与哈希表比较
4.匹配则返回结果集
在驱动表构建HASH表不能一次性的在内存中存放时:
1.第二个大表进行扫描
2.如果大表不能完全cache到可用内存的时候,大表同样会分成很多分区
3. 大表的第一个分区cache到内存
4.对大表第一个分区的数据进行扫描,并与哈希表进行比较,如果有匹配的纪录,添加到结果集里面
5.与第一个分区一样,其它的分区也类似处理。
6.所有的分区处理完后,ORACLE对产生的结果集进行归并,汇总,产生最终的结果。
使用hash join时,HASH_AREA_SIZE初始化参数必须足够的大,如果是9i,Oracle建议使用SQL工作区自动管理,设置WORKAREA_SIZE_POLICY 为AUTO,然后调整PGA_AGGREGATE_TARGET即可。适用情况如下:
1. 两个巨大的表之间的连接。
2. 在一个巨大的表和一个小表之间的连接。
注:在多表查询时,可用ordered提示来改变优化默认的驱动表,可用USE_HASH(table_name1 table_name2)提示来强制使用hash join。
nested loop(嵌套连接)
nested loop原理概述
对于被连接的数据子集较小的情况,nested loop连接是个较好的选择。nested loop就是扫描一个表,每读到一条记录,就根据索引去另一个表里面查找,没有索引一般就不会是 nested loops。一般在nested loop中, 驱动表满足条件结果集不大,被驱动表的连接字段要有索引,这样就走nested loop。如果驱动表返回记录太多,就不适合nested loops了。如果连接字段没有索引,则适合走hash join,因为不需要索引
分析:
1. 优化器根据基于规则RBO或基于成本CBO的原则,选择两个表中的一个作为驱动表,并指定其为外部表。
2. Oracle 优化器再将另外一个表指定为内部表。
3. Oracle从外部表中读取第一行,然后和内部表中的数据逐一进行对比,所有匹配的记录放在结果集中。
4. Oracle读取外部表中的第二行,再和内部表中的数据逐一进行对比,所有匹配的记录添加到结果集中。
5. 重复上述步骤,直到外部表中的所有纪录全部处理完。
6. 最后产生满足要求的结果集。
适用环境
1.快速返回第一批记录最快速的方法
2.驱动行源表(就是正在查找的记录)较小、
3.或者内部行源表已连接的列有惟一的索引或高度可选的非惟一索引时
优点 快速返回,使用索引
不足 内部表没有索引时效率差驱动表的数据量太大时效率差
注:可用ordered提示来改变CBO默认的驱动表,可用USE_NL(table_name1 table_name2)提示来强制使用nested loop。
3. merge join(合并连接)
Merge join原理概述
对连接的每个表做table access full;对table access full的结果进行排序;进行merge join对排序结果进行合并。sort merge join性能开销几乎都在前两步。一般是在没有索引的情况下,9i开始已经很少出现了,因为其排序成本高,大多为hash join替代了。通常情况下hash join的效果都比sort merge join要好,然而如果行源已经被排过序,在执行sort merge join时不需要再排序了,这时sort merge join的性能会优于hash join。在全表扫描再索引范围扫描再通过rowid进行表访问更可取的情况下,sort merge join会比nested loops性能更佳。
分析:
1.化器判断第一个源表是否已经排序,如果已经排序,则到第3步,否则到第2步。
2.第一个源表排序
3.优化器判断第二个源表是否已经排序,如果已经排序,则到第5步,否则到第4步。
4.第二个源表排序
5. 已经排过序的两个源表进行合并操作,并生成最终的结果集。
适用环境
1.在缺乏数据的选择性或者可用的索引时
2.两个源表都过于庞大(所选的数据超过表记录数的5%)时
1.适用于硬件条件较好时候的大数据量连接
优缺点
1. 不能使用到索引
2. 耗用大量内存和IO用于排序
3. 主要资源消耗临时内存块,磁盘I/O
4. 基于RBO
注:可用USE_MERGE(table_name1 table_name2)提示强制使用sort merge join。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/20948385/viewspace-666194/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/20948385/viewspace-666194/