--嵌套循环连接的使用情景
Nested loop joins are useful when the following conditions are true:
■ The database joins small subsets of data. ---与比较小的结果集进行连接
■ The join condition is an efficient method of accessing the second table.--连接条件有利于高效的访问第二张表
--嵌套循环连接涉及到的步骤
1. The optimizer determines the driving table and designates it as the outer table.
2. The other table is designated as the inner table.
3. For every row in the outer table, Oracle Da tabase accesses all the rows in the inner
table. The outer loop is for every row in the outer table and the inner loop is for
every row in the inner table. The outer loop appears before the inner loop in the
execution plan, as follows:
NESTED LOOPS
outer_loop
inner_loop
1、优化器决定驱动表并作为外部表(outer table)
2、其他表作为内部表(inner table)
3、当外部表每执行一次循环后,会在内部表查找符合连接条件的行
oracle 11gR2 嵌套循环的新特性
New Implementation for Nested Loop Joins Oracle Database 11g introduces a new
implementation for nested loop joins to reduce overall latency for physical I/O. When
an index or a table block is not in the buffer cache and is needed to process the join, a
physical I/O is required. Oracle Database 11g can batch multiple physical I/O requests
and process them using a vector I/O instead of processing them one at a time.
---当索引或者数据块不在buffer cache中oracle会使用批处理的方式处理多个物理I/O的请求
---使用 vector i/o 。避免一次一个地处理它们
scott@ORCL> select * from v$version where rownum=1;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
hr@ORCL> set autot traceonly
hr@ORCL> SELECT e.first_name, e.last_name, e.salary, d.department_name
2 FROM hr.employees e, hr.departments d
3 WHERE d.department_name IN ('Marketing', 'Sales')
4 AND e.department_id = d.department_id;
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 19 | 722 | 4 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 19 | 722 | 4 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL | DEPARTMENTS | 2 | 32 | 3 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | EMP_DEPARTMENT_IX | 10 | | 0 (0)| 00:00:01 |
| 5 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 10 | 220 | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("D"."DEPARTMENT_NAME"='Marketing' OR "D"."DEPARTMENT_NAME"='Sales')
4 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
可以看到department是第一个join的外部表,EMP_DEPARTMENT_IX 为第一个join的内部表
第一个join的结果集组成了第二个join的外部表,employee作为第二个连接的内部表。
--优化器何时使用嵌套循环连接
1、两张表有比较好的连接条件
2、外部表产生row source,然后检查内部表是否有匹配的行,如果有匹配的话放在结果集中
如果内部表的访问路径不依赖与外部表,那么你可以使用笛卡尔积连接。
3、嵌套循环的Hints /*+ use_nl(t1 t2) */