表连接有三种方式:nest loop,hash join 和sort merge.
1、nest loop
通过CBO确定驱动表,一般找小表作为驱动表。对驱动表中符合条件的每一行,都要扫描被驱动表,找到并返回所有符合的行。
优:没有前期准备工作(hash join要做hash分区,sort 要排序),直接就可以扫描数据并返回。若有合适索引则效率还可以。
劣:扫描被驱动表时是随机读。若被驱动表很大,则要多次全扫描被驱动表,随机读巨大,效率低;可通过建立合适索引来优化;效果有限
适用:适用于小表之间的连接,或有合适的索引,总体来说不适合大数据量。
2、hash join
先选出一个较小的表,基于连接列通过hash算法打散成多个分区桶(bucket)。这些分区最好能全部放入内存,列及数据都在内存中。然后将被驱动表连接列的每个hash值定位到bucket中。然后在每个小范围进行精确匹配。
优:在内存中操作,速度比sort merge快;
随机读只在小范围内进行,不会像nest loop那样扫全表,这样要精准很多,快很多;
各分区可并行进行,速度快;
劣:只能用于等值连接;
数据分布要均匀,若数据集中于某个bucket,则效率依然很差,执行起来就像是nest loop;
consistent gets比sort merge稍大;
适用:适用于大数据量。不依赖索引,但要保证数据分布合理。
3、sort merge
两个表都排序,占用PGA,很可能占用临时表空间。排序后连接。
仅仅是为了优化nest loop大量随机读。而nest loop随机读可以通过优化索引来减少。
优:不存在驱动表与被驱动表,不用抉择;
一次扫描排序后即可直接连接,不存在nest loop那样为了连接而多次扫描被驱动表的情况,一定程度上减少随机读;
劣:要使用排序区,数据量大时要使用临时表空间,速度低;
对索引使用的效果上不如nest loop。
适用:根据连结列已排序好的表。