首页 > Linux操作系统 > Linux操作系统 > 执行计划的执行顺序精解(4)
因为表LOCATIONS where 后面的的索引列LOCATION_ID是一个连接列,而非限制列,因此访问表的所有的rowid所得的中间结果集,就是全表的23条记录数,从执行计划的rows=23也可验证,值得注意的是,索引唯一性扫描,执行一次,得到了该表的所有的rowid.
(3),oracle进程得到两张表的中间结果集,DEPARTMENTS 表的一条记录,LOCATIONS表的23条记录,oracle优化器将计算成本损耗(如何计算成本损耗,有待进一步研究),决定使用哪种连接方式,本例使用nested loops嵌套循环的方式访问,从执行计划看,驱动表为DEPARTMENTS,即外层表,被驱动表为LOCATIONS,即内层表,优化器这样选择是正确的,因为DEPARTMENTS的结果集少,一条记录,而LOCATIONS的结果集多,23条记录,优化器使用这一条记录去匹配23条记录中的某一条记录,执行一次就可以了,如果,相反的话,需要执行23次,这样效率就低很多。这里执行b.location_id = d.location_id,注意,这一对连接列的数据源就是上述的两个中间结果集,具体,拆分上述的sql,就是下面的语句:
select * from hr.departments b,hr.locations d
where b.location_id = d.location_id
and b.department_id = 30;
得到的结果集就一条记录:
DEPARTMENT_ID DEPARTMENT_NAME MANAGER_ID LOCATION_ID LOCATION_ID STREET_ADDRESS POSTAL_CODE CITY STATE_PROVINCE COUNTRY_ID
30 Purchasing 114 1700 1700 2004 Charade Rd 98199 Seattle Washington US
这就是第一次nested loops产生的中间结果集,就一条记录,注意,使用DEPARTMENTS. LOCATION_ID=LOCATIONS.LOCATION_ID去匹配,即LOCATION_ID=1700就一条记录。
(8)oracle进程全表扫描EMPLOYEES,注意使用了a.department_id=30来过滤,导致得到的中间结果集为6条记录.
得到的结果集如下:
EMPLOYEE_ID FIRST_NAME LAST_NAME EMAIL PHONE_NUMBER HIRE_DATE JOB_ID SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
114 Den Raphaely DRAPHEAL 515.127.4561 1994/12/7 PU_MAN 11000.00 100 30
115 Alexander Khoo AKHOO 515.127.4562 1995/5/18 PU_CLERK 3100.00 114 30
116 Shelli Baida SBAIDA 515.127.4563 1997/12/24 PU_CLERK 2900.00 114 30
117 Sigal Tobias STOBIAS 515.127.4564 1997/7/24 PU_CLERK 2800.00 114 30
118 Guy Himuro GHIMURO 515.127.4565 1998/11/15 PU_CLERK 2600.00 114 30
119 Karen Colmenares KCOLMENA 515.127.4566 1999/8/10 PU_CLERK 2500.00 114 30
(2) oracle优化器将进行第二次nested loops,来产生中间结果集,数据源为(3)的一条记录和(8)的6条记录,拆分上述sql,使用如下sql进行nested loops:
select *
from hr.employees a, hr.departments b
where a.department_id = b.department_id
and b.department_id = 30;
驱动表为的行源为第一次nested loops的结果集,其实即使部门ID=30的这一条记录,被驱动表为employees,其实就是部门ID=30的6条记录,执行一次,匹配6条记录,因为employees的结果集内的6条记录的部门ID都是30,故而匹配6条记录。
(9)oracle进程接着对jobs表执行全表扫描,得到结果集为19条记录。
(1)oracle优化器将计算成本损耗(如何计算成本损耗,有待进一步研究),进行hash jion,将第二次nested loops的产生的结果集,即6条记录,为驱动行源,运用哈希函数对连接列(department_id)进行计算产生一张哈希表,放入PGA内存区的hash area 区域,接着扫描第二张表,即jobs,称为探测表,到内存区匹配记录数,显然,一条都没有匹配,该19条记录数被全部丢弃。
(0)SELECT STATEMENT 的最终结果集为6条记录数:
114 Den Raphaely DRAPHEAL 515.127.4561 1994/12/7 PU_MAN 11000.00 100 30 30 Purchasing 114 1700 PU_MAN Purchasing Manager 8000 15000 1700 2004 Charade Rd 98199 Seattle Washington US
119 Karen Colmenares KCOLMENA 515.127.4566 1999/8/10 PU_CLERK 2500.00 114 30 30 Purchasing 114 1700 PU_CLERK Purchasing Clerk 2500 5500 1700 2004 Charade Rd 98199 Seattle Washington US
118 Guy Himuro GHIMURO 515.127.4565 1998/11/15 PU_CLERK 2600.00 114 30 30 Purchasing 114 1700 PU_CLERK Purchasing Clerk 2500 5500 1700 2004 Charade Rd 98199 Seattle Washington US
117 Sigal Tobias STOBIAS 515.127.4564 1997/7/24 PU_CLERK 2800.00 114 30 30 Purchasing 114 1700 PU_CLERK Purchasing Clerk 2500 5500 1700 2004 Charade Rd 98199 Seattle Washington US
116 Shelli Baida SBAIDA 515.127.4563 1997/12/24 PU_CLERK 2900.00 114 30 30 Purchasing 114 1700 PU_CLERK Purchasing Clerk 2500 5500 1700 2004 Charade Rd 98199 Seattle Washington US
115 Alexander Khoo AKHOO 515.127.4562 1995/5/18 PU_CLERK 3100.00 114 30 30 Purchasing 114 1700 PU_CLERK Purchasing Clerk 2500 5500 1700 2004 Charade Rd 98199 Seattle Washington US
end.
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/21266384/viewspace-767737/ ,如需转载,请注明出处,否则将追究法律责任。