在查看sql执行计划时,我们会发现表的连接方式有多种,本文对表的连接方式进行介绍以便更好看懂执行计划和理解sql执行原理。 一
在查看sql执行计划时,我们会发现表的连接方式有多种,本文对表的连接方式进行介绍以便更好看懂执行计划和理解sql执行原理。
一、连接方式:
嵌套循环(Nested Loops (NL))
(散列)哈希连接(Hash Join (HJ))
二、连接说明:
1.Oracle一次只能连接两个表。不管查询中有多少个表,Oracle 在连接中一次仅能操作两张表。
2.当执行多个表的连接时,,优化器从一个表开始,将它与另一个表连接;然后将中间结果与下一个表连接,以此类推,直到处理完所有表为止。
三、表连接详解:
1.嵌套循环(Nested Loops (NL)):
嵌套循环实现机制(伪代码):
For r1 in (select rows from table_1 where colx={value})
loop
for r2 in (select rows from table_2 that match current row from table_1)
loop
output values from current row of table_1 and current row of table_2;
end loop;
End loop;
这段代码由两个循环构成。
嵌套循环中的这两个表通常称为外部表(outer table)和内部表(inner table)。
在嵌套循环连接中,外部表又称为驱动表(driver table)
伪代码中:table_1为驱动表,table_2为内表
从伪代码中可以看出该连接过程就是一个2层嵌套循环,所以外层循环的次数越少越好,这也就是我们为什么将小表或返回较小结果集的表作为驱动表的原因。
NEST LOOP JOIN COST = 从第一个表取得数据的成本 + 从第一个表得到结果的基数 Х 对第二个表访问一次的成本
所以嵌套循环一般适合于驱动表记录集比较少(<10000)且内表有高效索引访问方式。
使用USE_NL(table_1 table_2)可强制CBO 执行嵌套循环连接。
驱动表确定:驱动表【select rows from table_1 where colx={value} 】一般为根据where条件能得到较小结果集的表,而不一定是整个表记录比较小的表。
2.(散列)哈希连接(Hash Join (HJ)):
Hash join。
3.排序合并连接(Sort Merge Join (SMJ) ):
通常情况下散列连接的效果都比排序合并连接要好,然而如果行源已经被排过序,在执行排序合并连接时不需要再排序了,这时排序合并连接的性能会优于散列连接。可以使用USE_MERGE(table_1 table_2)来强制使用排序合并连接。
过程:将两个表排序,然后将排序后两个表合并。