Oracle SQL 查询优化.Part3

来源:互联网 发布:百度云用数据上传慢 编辑:程序博客网 时间:2024/06/06 02:14

一、union

1. union 的处理过程:

union all 是简单的将结果集合并后返回,想必大家都清楚,这里就不举例了。而 union 处理结果集时稍微复杂些,不仅去重,还会排序。union 的处理过程是先取出两个结果集,再用排序空间删除重复记录(所以,不仅仅是去除 union 连接起来的结果集之间的重复数据,而是在整个返回的结果集中去重)。

-- 没用 union 产生重复记录select emp.deptno from emp;

-- 和一个空集进行 union 连接,去重select emp.deptno from empunionselect emp.empno from emp where 1 = 2

上边第二个 sql 中 union 连接了一个有重复记录的结果集和一个空集,最终返回的结果集只有一条记录。所以,union 是在整个结果集中去重。

二、with 语句

1. with语法

with 语句的效果很想临时创建若干个视图(view),在 sql 执行完毕后销毁。with 可以创建多个这样“临时view”,而且创建次序以上之下,后边的可以引用前边已经创建好的“临时view”。

-- with 语法with e1 as(select emp.* from emp where emp.empsalary >= 3000),e2 as(select emp.* from emp where emp.deptno = 'dept02'),e3 as(select e1.empno, e1.deptno, e1.empsalary from e1, e2 where e1.empno = e2.empno)select * from e3;

e1 查询工资大于等于 3000 的员工,e2 查询部门在 dept02 的员工,e3 用empno 关联 e1、e2 产生的结果集表示“工资大于等于 3000,在 dept02 部门的所有员工”。在这里,e3 引用了e1 和 e2 两个“临时view”。

三、in 和 exists

1. in 与 exists 的区别:

在子查询中,in 是 把外表和内表做 hash 链接,exists 是把内表和外表做 loop 循环。一直以来都说“exists 比 in 效率高”貌似是不准确的。子查询(内)表大用 exists,子查询表小用 in。

例如:

表A(小表),表B(大表)

select * from A where id in(select id from B)  -->效率低,用到了A表上cc列的索引select * from A where exists(select id from B where A.id = B.id)
表A(大表),表B(小表)
select * from B where id in(select id from A)  -->效率高,用到了B表上cc列的索引select * from B where exists(select id from A where A.id = B.id)
exists 和 in 具体效率上的差异还有待验证。

1 0