OBA技能1-获取执行计划
OBA技能2-执行计划顺序
小仙我在学习索引执行行为的时候,有个疑惑? 那就是索引是找到一个值就马上回表,然后再找下一个值,再回表。
比如索引唯一扫描,索引范围扫描,索引全扫描,索引快速扫描。好像都是要回表。尤其是范围,不范围完后,再回表呢?像下面的索引范围扫描
它不是把INDEX RANGE SCAN 执行完了后 再执行TABLE ACCESS BY INDEX ROWID。而是SCAN 一次,TABLE一次。这样要反复执行好多次,具体多少次,就看评估值Cardinatily 也就是ROW值。
而表连接是,是结果集的链接,换言之就是先把表要的数据找出来后,再跟后面的表关联。
那什么时候是一次一条数据,什么时候是一次全部数据呢?
这要看两个方面,
1 是操作方法;
2 是表连接方式;
所谓操作方法 就是上面说的过程。 比如说INDEX RANGE SCAN 就是一次返回一条数据,然后执行第二方法,回表找具体数据。有的方法 TABLE ACCESS FULL 全表扫描 它就是一次返回全部符合条件的数据。
表连接方法,常见的有3种分别是
1 NESTED LOOPS
2 HASH JOIN
3 SORT JOIN MERGE JOIN
第一个是嵌套循环关联,第二个是HASH,第三个SORT 排序。
第一个链接 类似于JAVA开发当中的 双循环
for a (i=1;i++;i<1000)
{
x=y*z;
for b( h=1;h++; h<10)
{
o=x*100;
}
}
先执行X=Y*Z 然后再执行内循环,外循环执行1000次,而内循环要执行10次,外乘以外循环次数 10*1000=10000次。
这图没有表现我要说的,我大致画一下
NESTED LOOPS
TABLE ACCESS BY INDEX ROWID
INDEX RANGE SCAN
TABLE ACCESS FULL
这样的执行计划,NESTED LOOPS 不会等 外循环返回所有数据后去执行内循环 也就是TABLE ACCESS FULL。而是外循环返回1条记录,就执行一次内循环。而要是外循环是TABLE ACCESS FULL 那就必须等待外循环找完全部数据后才执行内循环。
所以这个NESTED LOOPS 是受到具体执行方法的影响。另外两种不受影响。
OBA常用术语叫驱动表,它就是指外循环,也就是先被执行的表,一般都是兄长级别的表。另外两个链接也是兄长级别当驱动表。
所以 驱动表 必须是小表,确切地说是返回结果集小的,也就是返回行数最少的。否则向上面的双循环列子样,外循环要执行1000次,而内循环执行10次,可内循环被外循环强制执行了1万次。
你要是说颠倒过来,内循环还是要执行1万次。可是总体来说是10次+1万次,而不颠倒过来是1000次+1万次。多了990次。
另外谈个顺序,在很多表关联的SQL中,表与表之间的关联是单向的,第一个表与第二个表关联后形成了结果集,保存在PGA的数据。然后再跟第三个表关联再形成结果集保留在PGA里,接着跟第4个表关联。
而不是第1个表与第2个表关联形成结果集1,然后第3个表与第4个表关联形成结果集2,最后结果集1和结果集2关联。执行计划不能被并行执行。
NESTED LOOPS 是两个表等值关联,返回少量数据;
HASH JOIN 是两个表等值关联,返回大量数据;
HASH JOIN 会选择返回数据较少的表,把表的SELECT列和JOIN列放入PGA中,然后对另外个表的JOIN列进行HASH取值,然后再跟PGA的驱动表JOIN列进行匹配关联。
SORT MEGER JOIN 处理两个表非等值关联 >,>=,<,<=,<>.
先对两个表根据JOIN列进行排序,选择数据较小的表作为驱动表,然后跟排好序的另外个表进行匹配。驱动表返回多少行,另外个表就要匹配多少次。
SELECT STATEMENT
MERGE JOIN
TABLE ACCESS BY INDEX ROWID
INDEX RANGE SCAN
SORT JOIN
TABLE ACCESS FULL
并且两个表的数据都要放进内存PGA进行匹配,如果内存放不下,就放到磁盘上。
所以这里全部数据提到内存进行匹配, 不受INDEX RANGE SCAN 单行的影响。
CARTESIAN JOIN 笛卡尔 ,这是两个表没有连接列造成的。
MEGER JOIN CARTESIAN 也是笛卡尔.
SEMI JOIN 叫做半连接 两个表关联只返回1个表的数据,一般都是IN和EXISTS。会出现 MERGE JOIN SEMI,NESTEDLOOPS SEMI的执行方法。都属于半连接。
ANTI JOIN 是反连接。是NOT IN,NOT EXISTS,执行计划的方法名字带有ANTI 就是反连接,表现有 MERGE JOIN ANTI NA;NESTED LOOPS ANTI
FILTER 连接 FILTER这个字眼在执行计划有两个意思,1个就是过滤,另外一个是关联,类似于NESTED LOOPS。主要看FILTER下面是否有两个以上的儿子(后代)。
为啥不直接用NESTED LOOPS 表示呢?因为FILTER告诉你 其中子查询没有被展开。