隨筆 - 6  文章 - 129  trackbacks - 0
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          常用鏈接

          留言簿(14)

          隨筆檔案(6)

          文章分類(467)

          文章檔案(423)

          相冊

          收藏夾(18)

          JAVA

          搜索

          •  

          積分與排名

          • 積分 - 827240
          • 排名 - 49

          最新評論

          閱讀排行榜

          評論排行榜

          轉自:http://blog.csdn.net/huangyunzeng2008/archive/2010/01/18/5209499.aspx 
          今天優化了一個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;

          這里沒有使用嵌套子查詢,而是使用了關聯子查詢 ,這樣實際上也是很好理解的,但是往往我們很少這樣寫。

          四、總的來說我還是很喜歡下面的寫法,在數據量很大的情況下,對性能的提高真的不少,但是在數據量小的情況下似乎看不出什么效果。實際上也是,如果 數據量小,根本不會涉及到優化,我在這里說也沒什么用。如果覺得自己的子查詢有問題,看看能不能把嵌套子查詢轉化為關聯子查詢,效果還是挺明顯的。



          posted on 2010-11-09 17:25 Ke 閱讀(1559) 評論(0)  編輯  收藏 所屬分類: oracle
          主站蜘蛛池模板: 闵行区| 改则县| 乌什县| 平武县| 常德市| 安岳县| 自贡市| 岢岚县| 保山市| 河曲县| 汕尾市| 石屏县| 广宗县| 杭州市| 巴南区| 建平县| 万载县| 曲阜市| 梧州市| 凤冈县| 会泽县| 博爱县| 桐城市| 二手房| 宝鸡市| 林州市| 乡宁县| 象州县| 木兰县| 大城县| 济源市| 武川县| 蒙阴县| 高陵县| 霍林郭勒市| 大荔县| 博野县| 东乡县| 莱州市| 韶关市| 得荣县|