ORACLE数据库SQL优化---)Oracle表连接类型(一)

2014-11-24 16:55:49 · 作者: · 浏览: 3

一,当优化器解析含表连接的目标SQL时,它除了会根据目标SQL的SQL文本的写法来决定表连接的类型之外,还必须决定如下三件事情才能得到最终的执行计划。

1,表连接顺序

不管目标SQL中有多少个表做表连接,ORACLE在实际执行该SQL时都只能先两两做表连接,再依次执行这样的两两表连接过程,直到目标SQL中所有的表都已连接完毕。所以这里的表连接顺序包含两层含义:一层含义是当两个表做连接时,优化器需要决定这两个表中谁是驱动表(outer table),谁是被驱动表(inner table);另一层含义是当多个表(超过2个表)做表连接时,优化器需要决定这些表中谁和谁先做连接,然后决定这个表连接结果所在的结果集再和剩余表中哪一个再做表连接,这个两两做表连接的过程会一直持续下去,直到目标SQL中所有的表都已连接完为止。

2,表连接方法

在ORACLE中,两个表之间的连接方法有排序合并连接(Sort Merge),嵌套循环连接(Nested Loops),哈希连接(Hash Join),笛卡尔连接(Cross Join)这四种。

3,访问单表的方法

对于优化器来说,仅决定表的连接顺序和表的连接方法是不够的,这不足以得到目标SQL的最终执行计划,因为优化器在对目标SQL中的各个表两两连接时,还必须决定如何去获取存储在这些表里的不同维度的数据,即优化器还要决定访问单表的方法。比如在访问单表的时候,是采用全表扫描还是走索引,如果是走索引,应该是走什么样的索引(Index unique scan, index range scan, index full scan,index fast full scan, index skip scan)。

二,表连接类型

1,内连接(Inner Join):是指表连接的连接结果只包含哪些完全满足条件的记录。

下面来看一个内连接的例子:

create table t1(col1 number,col2 varchar2(10));
create table t2(col2 varchar2(10),col3 varchar2(10));
insert into t1 values(1,'A');
insert into t1 values(2,'B');
insert into t1 values(3,'C');

insert into t2 values('A','A2');
insert into t2 values('B','B2');
insert into t2 values('D','D2');

两个表里的数据如下:

SQL> select * from t1;

COL1 COL2
---------- ----------
1 A
2 B
3 C

SQL> select * from t2;

COL2 COL3
---------- ----------
A A2
B B2
D D2

我们来看下如下的内连接:

SQL> select t1.col1,t1.col2,t2.col3 from t1,t2 where t1.col2=t2.col2;

COL1 COL2 COL3
---------- ---------- ----------
1 A A2
2 B B2

从上面的内连接的结果可以看出,内连接的结果确实只包含了哪些完全满足连接条件的记录。上面的写法是ORACLE自己的写法。这个和标准的SQL中的内连接写法不同,下面我们来看下标准的SQL的内连接的写法如下:

SQL> select t1.col1,t1.col2,t2.col3 from t1 join t2 on (t1.col2=t2.col2);

COL1 COL2 COL3
---------- ---------- ----------
1 A A2
2 B B2

从上面可以看出查询出来的结果是一样的。

2,外连接(Outer Join)是对内连接的一种扩展,它是指表连接结果除了包含那些完全满足连接条件的记录之外还会包含驱动表(outer table)中所有不满足该连接条件的记录。

标准的SQL外连接分为左连接(left outer join),右连接(right outer join)和全连接(full outer join)这三种。他们在标准的SQL中所对应的关键字分别是left out join,right out join,full outer join。这里的Outer table就是驱动表。当做外连接的时候,驱动表中所有不满足该连接条件的记录所对应的被驱动表中的查询列均会为NULL值来填充。可以简单得把全连接理解为先做左连接,再做右连接,最后对左连接和右连接的连接结果做一个UNION操作。(注意,虽然可以这么理解,但ORACLE在实际执行全连接时不会这么做)。

下面来看几个外连接的例子:

如下是左连接的例子:

SQL> select t1.col1,t1.col2,t2.col3 from t1 left join t2 on (t1.col2=t2.col2);

COL1 COL2 COL3
---------- ---------- ----------
1 A A2
2 B B2
3 C

SQL> select t1.col1,t1.col2,t2.col3 from t1 left outer join t2 on (t1.col2=t2.col2);

COL1 COL2 COL3
---------- ---------- ----------
1 A A2
2 B B2
3 C

注意:left outer join 可以简写成left join.

从上面可以看出,做连接的执行结果确实是除了包含所有满足条件连接条件的记录外,还包含驱动表(T1)中所有不满足该连接条件的记录。同时,驱动表中所有不满足该连接条件的记录所对应的被驱动表中的查询列均以NULL值来填充。

如下是右连接的例子:

SQL> select t1.col1,t1.col2,t2.col3 from t1 right join t2 on (t1.col2=t2.col2);

COL1 COL2 COL3
---------- ---------- ----------
1 A A2
2 B B2
D2

SQL> select t1.col1,t1.col2,t2.col3 from t1 right outer join t2 on (t1.col2=t2.col2);

COL1 COL2 COL3
---------- ---------- ----------
1 A A2
2 B B2
D2

注意:right outer join 可以简写成right join.

从上面可以看出,做连接的执行结果确实是除了包含所有满足条件连接条件的记录外,还包含驱动表(T2)中所有不满足该连接条件的记录。同时,驱动表中所有不满足该连接条件的记录所对应的被驱动表中的查询列均以NULL值来填充。

如下是全连接的例子:

SQL> select t1.col1,t1.col2,t2.col3 from t1 full outer join t2 on (t1.col2=t2.col2);

COL1 COL2 COL3
---------- ---------- ----------
1 A A2
2 B B2
3 C
D2

SQL> select t1.col1,t1.col2,t2.col3 from t1 full join t2 on (t1.col2=t2.col2);

COL1 COL2 COL3
---------- ---------- ----------
1 A A2
2 B B2
3 C
D2

从上面可以看出,全连接的结果确实是除了