对于该查询语句的执行,如果用代码可以描述成这样:
for (rec1 is t1’s first record; rec1!=NULL; rec1=rec1->next)
for(rec2 in t2’s first record that match c1=d1; d1=c1; rec2=rec->next)
{
put result(rec1.c1,rec1.c2,rec2.d1) into result set;
}
数据库执行该执行语句的步骤也是类似的,下面是执行该执行语句的步骤:
1) TAF(T1)(“TABLE ACCESS (FULL) OF 'T1'”的简写)取得表T1的第一条记录(1,1)传递给NL(“NESTED LOOPS”的简写),将控制权传递给NL。
2) 操作符NL将控制权传递给第二个孩子IRS(IT2D1)(“INDEX (RANGE SCAN) OF 'IT2D1'”的简写)。
3) IRS(IT2D1)使用键值(1)去命中索引IT2D1对应的B树,得到索引记录(1,rowid1)。将d1对应的数据(1)传递给NL,将控制权传递给NL。注意,在本例中,将d1的数据上传是因为select中出现了d1,也就是说要将d1的值传给客户端,如果select中没有d1,此处就和上例中是一样的,不需要传递d1给上层。
4) 操作NL组合生成记录(1,1,1)(对应select项(c1,c2,d1))传给SS,将控制权传给SS。
5) 操作符SS将记录(1,1,1)放入结果集,将控制权传给NL。
6) NL将控制权传给IRS(IT2D1)。此处传给IRS(IT2D1)的原因是,it2d1是非唯一索引,可能有两条以上的记录符合d1=1。
7) IRS(IT2D1)取得下一条记录(2,rowid2),因为2!=1,所以对应d1=1的索引查找已经结束,通知NL,将控制权限传递给NL。
8) NL控制权传给TAF(T1)。
9) TAF(T1)取得下一条记录(2,2)传递给NL,将控制权传给NL。
10) NL将控制权传给IRS(IT2D1)。
11) IRS(IT2D1)使用键值(2)去命中索引IT2D1对应的B树,得到索引记录(2,rowid2)。将d1对应的数据(2)传递给NL,将控制权传递给NL。
12) 操作NL组合生成记录(2,2,2)传给SS,将控制权传给SS。
13) 操作符SS将记录(2,2,2)放入结果集,将控制权传给NL。
14) NL将控制权传给IRS(IT2D1)。
15) IRS(IT2D1)取得下一条记录(3,rowid3),因为3!=2,所以对应d1=2的索引查找已经结束,通知NL查找结束,将控制权限传递给NL。
16) NL控制权传给TAF(T1)。
17) TAF(T1)取得下一条记录,发现已经扫描结束,通知NL扫描结束,将控制权传给NL。
18) NL通知SS扫描结束,将控制权传给SS。
19) SS将结果集(包含记录(1,1,1)、(2,2,2))发送给客户端。据库执行该执行语句的步骤也是类似的,下面是执行该执行语句的步骤:
3.使用唯一索引的嵌套连接的执行计划该如何理解?
测试数据与1中描述的一样。删除原来的非唯一索引,建立唯一索引:
drop index it2d1;
create unique index iut2d1 on t2(d1);
查询语句:
select /*+ index(t2) */ c1,c2,d1 from t1 inner join t2 on c1=d1;
对应的执行计划:
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=2 Bytes=78)
1 0 NESTED LOOPS (Cost=2 Card=2 Bytes=78)
2 1 TABLE ACCESS (FULL) OF 'T1' (TABLE) (Cost=2 Card=2 Bytes
=52)
3 1 INDEX (UNIQUE SCAN) OF 'IUT2D1' (INDEX (UNIQUE)) (Cost=0
Card=1 Bytes=13)
该执行计划与2中描述的执行过程类似:
1) TAF(T1)(“TABLE ACCESS (FULL) OF 'T1'”的简写)取得表T1的第一条记录(1,1)传递给NL(“NESTED LOOPS”的简写),将控制权传递给NL。
2) 操作符NL将控制权传递给第二个孩子IUS(IUT2D1)(“INDEX (UNIQUE SCAN) OF 'IUT2D1''”的简写)。
3) IUS(IUT2D1)使用键值(1)去命中索引IUT2D1对应的B树,得到索引记录(1,rowid1)。将d1对应的数据(1)传递给NL,将控制权传递给NL。
4) 操作NL组合生成记录(1,1,1)(对应select项(c1,c2,d1))传给SS,将控制权传给SS。
5) 操作符SS将记录(1,1,1)放入结果集,将控制权传给NL。
6) NL控制权传给TAF(T1)。因为iut2d1是唯一索引,所以只可能有一条记录满足d1=1,所以此时不需要将控制权限再传给IUS(IUT2D1)。
7) TAF(T1)取得下一条记录(2,2)传递给NL,将控制权传给NL。
8) NL将控制权传给IRS(IUT2D1)。
9) IUS(IUT2D1)使用键值(2)去命中索引IUT2D1对应的B树,得到索引记录(2,rowid2)。将d1对应的数据(2)传递给NL,将控制权传递给NL。
10) 操作NL组合生成记录(2,2,2)传给SS,将控制权传给SS。
11) 操作符SS将记录(2,2,2)放入结果集,将控制权传给NL。
12) NL控制权传给TAF(T1)。
13) TAF(T1)取得下一条记录,发现已经扫描结束,通知NL扫描结束,将控制权传给NL。
14) NL通知SS扫描结束,将控制权传给SS。
15) SS将结果集(包含记录(1,1,1)、(2,2,2))发送给客户端。