日期:2014-05-16  浏览次数:20444 次

oracle 连接查询

?

oracle表连接问题

连接树:
oracle数据库引擎每次只能处理两个数据集
左节点
右节点

左深树
右深树

1 交叉连接
 select  emp.sal,dept.dname from emp,dept
 select emp.sal,dept.dname from emp cross join dept
2 条件连接[内连接]
  select emp.sal,dept.dname from emp,dept where emp.sal>9000
  select emp.sal,dept.dname from emp inner join dept on emp.sal>9000
3 等值连接
  select emp.sal,dept.dname from emp,dept where emp.deptno=dept.deptno
  select emp.sal,dept.dname from emp join dept on emp.deptno = dept.deptno
4 自连接
  select a.ename as 员工, b.ename as 经理 from emp a,emp b where a.mgr=b.empno
5 外连接
  select e.ename,d.dname from emp e,dept d where e.deptno(+) = d.deptno;
  select e.ename,d.dname from emp left join dept d on e.deptno = d.deptno
6 半连接
 select deptno,dname from dept where deptno in(select deptno from emp)
 select deptno,dname from dept where exists(select deptno from emp where emp.deptno=dept.deptno)
7 反连接
 select deptno,dname from dept where deptno not in(select deptno from emp)
 select deptno,dname from dept where not exists(select deptno from emp where emp.deptno=dept.deptno)

嵌套连接nested loops join
查询的时候关心读取的次数,而不关心每次吞吐量的大小,小表驱动大表
一定注意是小表驱动大表

操作系统和数据库它所关心的是 IO的次数,并不关心每次IO的吞吐量

select * from emp scott.emp e,scott.dept d where e.deptno = d.deptno

create table t1(id int,name varchar2(20));
create table t2(id int, name varchar2(20),tid int);

select /*+ leading(t1) user_n1(t2)*/ from t1,t2 where t1.id=t2.tid and t1.name='aaa';


decare

begin
 for i in 1..4 loop
    insert into t1 value(i,'aaa');
 end loop;

等待事件 db file sequential read
         db file scattered read 
end;

1.如果内部表连接列上上没有索引,或者索引的选择性很差,那么nest性能非常差。
2.如果驱动表比较大,那么不建议使用嵌套循环
合并连接(不常用)
merge join

select * from t1,t2 wehre t1.id =t2.id
1.当索引范围扫描的是利用索引的连接列
2.合并连接的前一个操作已经对数据进行了正确的排序

哈希连接
hash join
只能针对 = 连接

1 将小表加到PGA里面,希望PGA能够容纳开这个小表(cluster table)
2 对大表进行全表扫描。先取一部分放到pga中,和pga中的小表进行hash join
特点 相对来说比较消耗cpu,但又不是问题
cluster table 最好能够被gpa容纳
成本固定