--表连接方式
1.Hash join:优化器使用两个表中较小的表(或数据源)利用连接键(HASH KEY)在内存中建立散列表(HASH表),然后扫描较大的表并探测散列表,找出与散列表匹配的行。如果hash表太大则无法在内存中完全放入,这时候优化器就分成不同区,把不能放入内存的分区放入到磁盘临时段,此时有较大的临时段来提高i/o性能。默认值指定方式:USE_HASH(table_name1 table_name2)
2.Nested loops:工作方式是从一张表(驱动表outer table,结果集比较小)中读取数据,访问另一张表(通常是索引,inner table)来做匹配,nested loops适用的场合是当一个关联表比较小的时候,效率会更高。默认值指定方式:USE_NL(table_name1 table_name2)
3.Merge Join 是先将关联表的关联列各自做排序,然后从各自的排序表中抽取数据,到另一个排序表中做匹配,因为merge join需要做更多的排序,所以消耗的资源更多。 通常来讲,能够使用merge join的地方,hash join都可以发挥更好的性能。
默认值指定方式:USE_MERGE(table_name1 table_name2)
4.Semi-join
通常出现在使用了exists或in的sql中,所谓semi-join即在两表关联时,当第二个表中存在一个或多个匹配记录时,返回第一个表的记录;
与普通join的区别在于semi-join时,第一个表里的记录最多只返回一次;
5.Anti-join
而anti-join则与semi-join相反,即当在第二张表没有发现匹配记录时,才会返回第一张表里的记录;
当使用not exists/not in的时候会用到,两者在处理null值的时候会有所区别
何时选择anti-join
1 使用not in且相应列有not null约束
2 not exists,不保证每次都用到anti-join
当无法选择anti-join时,oracle常会采用filter替代
--not exists与not in的区别在于not exists不受null值影响
6.迪卡尔积连接:当两个表没有任何连接条件时会使用此连接方式。
注意
Oracle在解析sql时候会尽可能的把子查询转换为表连接
Oracle在以下情况不会使用semi-join
1、 使用distinct或者union
2、 Exists/in子查询中使用了or
Hash_sj/merge_sj/nl_sj都是关于semi-join的一些hint