8.3.14.1 循环嵌套链接(NESTED LOOP)
嵌套循环链接的内部处理的流程如下。
(1)Oracle 优化器根据基于规则RBO或基于成本CBO的原则,选择两个表中的一个作为驱动表,并指定其为外部表。
(2)Oracle 优化器再将另外一个表指定为内部表。
(3)Oracle从外部表中读取***行,然后和内部表中的数据逐一进行对比,所有匹配的记录放在结果集中。
(4)Oracle读取外部表中的第二行,再和内部表中的数据逐一进行对比,所有匹配的记录添加到结果集中。
(5)重复上述步骤,直到外部表中的所有记录全部处理完。
(6)***产生满足要求的结果集。
通过查询SQL语句的执行计划可以看出哪个表是外部表,哪个是内部表,如:select a.user_name,b.dev_no
from user_info a, dev_info b
wherea.user_id=b.user_id;
执行计划:SELECT STATEMENTOptimizer=CHOOSE
NESTED LOOPS
TABLE ACCESS (FULL) OF 'USER_INFO'
TABLE ACCESS (FULL) OF 'DEV_INFO'
使用嵌套循环链接是一种从结果集中提取***批记录最快速的方法。在驱动行源表(就是正在查找的记录)较小或者内部行源表已链接的列有惟一的索引或高度可选的非惟一索引时, 嵌套循环链接效果是比较理想的。嵌套循环链接比其他链接方法有优势,它可以快速地从结果集中提取***批记录,而不用等待整个结果集完全确定下来。这样,在理想情况下,终端用户就可以通过查询屏幕查看***批记录,而在同时读取其他记录。不管如何定义链接的条件或者模式,任何两行记录源可以使用嵌套循环链接,所以嵌套循环链接是非常灵活的。
然而,如果内部行源表(读取的第二张表)已链接的列上不包含索引或者索引不是高度可选时,嵌套循环链接效率是很低的。如果驱动表的记录非常庞大时,其他的链接方法可能更加有效。
一般在nested loop中, 驱动表满足条件结果集不大,被驱动表的链接字段要有索引,这样就有nested loop。如果驱动表返回记录太多,就不适合nested loops了。如果链接字段没有索引,则适合走hash join,因为不需要索引。
可以通过在SQL语句中添加HINTS,强制Oracle优化器产生嵌套循环链接的执行计划。select /*+ use_nl(a b) */ a.user_name,b.dev_no
from user_info a, dev_info b
wherea.user_id=b.user_id;
【责任编辑:云霞 TEL:(010)68476606】
点赞 0