关联子查询与嵌套子查询
来源:互联网 发布:淘宝如何查看投诉结果 编辑:程序博客网 时间:2024/04/28 14:59
今天优化了一个sql语句,感觉速度好像是快了点,自己想想觉得也是,下面给出类似的例子,工作中的表就不拿来举例了。实际我们平常都在凭着自己的感觉在写SQL,其实跳出那个圈子你会发现能写出更好的。
一、先给出我的表和数据,这里数据量少,可能不明显,只是表明一下这个意思!
create table EMP( EMPNO NUMBER(4) not null, ENAME VARCHAR2(10), JOB VARCHAR2(9), MGR NUMBER(4), HIREDATE DATE, SAL NUMBER(7,2), DEPTNO NUMBER(2));insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO)values (7369, 'SMITH', 'CLERK', 7902, to_date('17-12-1980', 'dd-mm-yyyy'), 800, 20);insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO)values (7499, 'ALLEN', 'SALESMAN', 7698, to_date('20-02-1981', 'dd-mm-yyyy'), 1600, 30);insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO)values (7521, 'WARD', 'SALESMAN', 7698, to_date('22-02-1981', 'dd-mm-yyyy'), 1250, 30);insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO)values (7566, 'JONES', 'MANAGER', 7839, to_date('02-04-1981', 'dd-mm-yyyy'), 2975, 20);insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO)values (7654, 'MARTIN', 'SALESMAN', 7698, to_date('28-09-1981', 'dd-mm-yyyy'), 1250, 30);insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO)values (7698, 'BLAKE', 'MANAGER', 7839, to_date('01-05-1981', 'dd-mm-yyyy'), 2850, 30);insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO)values (7782, 'CLARK', 'MANAGER', 7839, to_date('09-06-1981', 'dd-mm-yyyy'), 2450, 10);insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO)values (7788, 'SCOTT', 'ANALYST', 7566, to_date('19-04-1987', 'dd-mm-yyyy'), 3000, 20);insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO)values (7844, 'TURNER', 'SALESMAN', 7698, to_date('08-09-1981', 'dd-mm-yyyy'), 1500, 30);insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO)values (7876, 'ADAMS', 'CLERK', 7788, to_date('23-05-1987', 'dd-mm-yyyy'), 1100, 20);insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO)values (7900, 'JAMES', 'CLERK', 7698, to_date('03-12-1981', 'dd-mm-yyyy'), 950, 30);insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO)values (7902, 'FORD', 'ANALYST', 7566, to_date('03-12-1981', 'dd-mm-yyyy'), 3000, 20);insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO)values (7934, 'MILLER', 'CLERK', 7782, to_date('23-01-1982', 'dd-mm-yyyy'), 1300, 10);commit;
二、假设有这样一个需求,我要得到这个表中所有低于所在部门平均工资的员工的基本信息。很自然的 我们会写出这样的SQL:
SELECT * FROM emp A WHERE A.sal < (SELECT AVG(sal) FROM emp B WHERE A.deptno = B.deptno);
这种写法是很通常的写法,也很好理解,从字面上看都知道是什么意思!但是在一个很大的表中这样来统计是很慢很慢的,对于每一条记录都要嵌套的查询一个子查询,这样对性能影响是很大的。
三、为什么不跳出这个思维的定式,换一种方法来统计呢,我给出下面的方法:
SELECT A.* FROM emp A, (SELECT deptno, AVG(sal) sal FROM emp GROUP BY deptno) B WHERE A.deptno = B.deptno AND A.sal < B.sal;
这里没有使用嵌套子查询,而是使用了关联子查询 ,这样实际上也是很好理解的,但是往往我们很少这样写。
四、总的来说我还是很喜欢下面的写法,在数据量很大的情况下,对性能的提高真的不少,但是在数据量小的情况下似乎看不出什么效果。实际上也是,如果数据量小,根本不会涉及到优化,我在这里说也没什么用。如果觉得自己的子查询有问题,看看能不能把嵌套子查询转化为关联子查询,效果还是挺明显的。
- 关联子查询与嵌套子查询
- 关联子查询与嵌套子查询
- 关联子查询与嵌套子查询
- 关联子查询与嵌套子查询
- 关联子查询-嵌套子查询
- 关联子查询+嵌套子查询
- 跨库嵌套子查询和关联子查询
- MySQL的关联查询与子查询
- oracle关联查询与子查询例子
- 相关子查询(关联子查询)和嵌套子查询
- sql嵌套子查询
- SQL嵌套子查询
- SQL嵌套子查询
- 七、嵌套子查询
- 3.8嵌套子查询
- hive嵌套子查询
- oracle子查询嵌套查询
- Update 关联子查询
- Remove实践之二
- 遗传程序设计与自动程序设计【转】
- 追求什么……
- ASP.NET中常用的存储过程
- 虚拟键值表【转】
- 关联子查询与嵌套子查询
- listbox消息大全【转】
- C# FTP下载一目录下所有文件夹及文件
- 深入理解C语言指针的奥秘[转]
- 接触 CORBA 内幕: IOR、GIOP 和 IIOP
- 注册表编程【转】
- C++ object model 图片表示
- oracle DBMS_LOCK.SLEEP()的使用
- Eclipse中设置编码的方式