Oracle的表连接及优化

表关联中的几种连接方式及对应的优化方法

表连接的几种常见类型

1、嵌套循环(Nested Loops Join)

2、哈希连接(Hash Join)

3、排序合并(Merge Sort Join)


各类连接的差异

访问次数

嵌套循环:驱动表返回几行,被驱动表就访问多少次 哈希连接:驱动表和被驱动表都是最多访问1次 排序合并:驱动表和被驱动表都是最多访问1次

驱动顺序

嵌套循环:有驱动顺序 哈希连接:有驱动顺序 排序合并:无驱动顺序

排序差别

嵌套循环:无需排序 哈希连接:无需排序(HASH_AREA_SIZE)——会消耗内存用于建HASH表 排序合并:无需排序(SORT_AREA_SIZE)

限制场景

嵌套循环:无任何限制 哈希连接:连接条件是<> > < 或者like导致无法使用 排序合并:连接条件是<>或者like导致无法使用


索引与各类连接的经典优化

嵌套循环:驱动表限制条件有索引,被驱动表连接条件有索引

所谓驱动表即在执行计划的NESTED LOOPS范围内,在前面的表; 驱动表的限制条件建索引是为了缩小扫描驱动表的时间,快速返回限制条件的少许几条记录;然后再传递给被驱动表关联,所以在被驱动表的关联列上建索引

哈希连接:索引列在表连接中无特殊要求,与单表情况无异 排序合并:索引消除排序

1
select /*+ leading(t1) use_nl(t2)*/ * from t1,t2 where t1.id = t2.id and t.id = ..

leading(t1)表示强制先访问t1表,即t1表作为驱动表 嵌套循环中,驱动表返回多少条记录,被驱动表就访问多少次。 所以要特别注意驱动表的顺序(不同的顺序,buffers不同,starts也不同),小的结果集先访问,大的结果集后访问,才能保证被驱动表的访问次数降到最低,提升性能

1
select /*+ leading(t1) use_hash(t2)*/ * from t1,t2 where t1.id = t2.id and t.id = ..

在hash连接中,驱动表和被驱动表都只会访问0次或者1次 t2访问0次:数据存在t1表但不存在t2表 t1访问0次:条件1=2 驱动表顺序不同,buffers相同,但Used-Mem有差异,小表做驱动表时,该值小

1
select /*+ ordered use_merge(t2)*/ * from t1,t2 where t1.id = t2.id and t.id = ..

排序合并连接和hash连接一样,t1表和t2表都只会访问0次或者1次 排序合并连接没有驱动表和被驱动表的概念

所以嵌套循环连接和哈希连接有驱动顺序,驱动表的顺序不同将影响表连接的性能,而排序合并连接没有驱动概念,无论哪张表在前都无妨。 嵌套循环里没有用到Used-Mem,而哈希和排序合并连接的执行计划里有此关键词,用于哈希连接的建立hash表和排序合并连接的排序。

许文忠 wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!