<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    人在江湖

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      82 Posts :: 10 Stories :: 169 Comments :: 0 Trackbacks
    這篇文字主要討論sql的一般編寫原則。下一篇討論根據(jù)執(zhí)行計劃進行調優(yōu)的話題。
    網上這類文章很多,但往往只是給出結論,比如,這樣寫sql會比那樣寫sql效率更高。閱讀者如果打算打開數(shù)據(jù)庫自己做一遍實驗,看看效率差異到底有多少,需要自己造數(shù)據(jù),還是比較麻煩。這篇文字會把DDL和DML以及sql的執(zhí)行時間都寫出來,一方面給一個更直觀的印象,另一方面方便閱讀者自己實驗。
    以Oracle為實驗用數(shù)據(jù)庫,使用著名的emp表。安裝oracle數(shù)據(jù)庫之后,scott用戶的密碼是tiger. 在他的schema下有幾張sample表,很多sql教程都以這幾張表為基礎. 據(jù)說,熟悉oracle數(shù)據(jù)庫的人提到smith這個人名,就能聯(lián)想起sample表中他的工作是clerk. emp表就是sample表之一。這張表原始數(shù)據(jù)只有14行,為了體現(xiàn)不同sql性能上的差異,我們需要多填充一些數(shù)據(jù)進去。作為填充數(shù)據(jù)的預備知識,我們可以看一下如何生成一系列從小到大的id:
    SELECT ROWNUM
    FROM DUAL
    CONNECT BY LEVEL < 10000;
    填充隨機數(shù)據(jù)可以借助于dbms_random包,不想覆蓋已有的表,所以新創(chuàng)建一個表結構基本一樣的: 
    create table emp_new
    as
    select level                                                          empno,
           SYS.dbms_random.String('u', SYS.dbms_random.value(3,10))       ename,
           SYS.dbms_random.String('u', SYS.dbms_random.value(3,9))        job,
           round(SYS.dbms_random.value(1000,9999))                        mgr,
           TO_DATE (   ROUND (DBMS_RANDOM.VALUE (128))
                        || '-'
                        || ROUND (DBMS_RANDOM.VALUE (112))
                        || '-'
                        || ROUND (DBMS_RANDOM.VALUE (19802012)),
                        'DD-MM-YYYY'
                       )                                                   hiredate,
            round(SYS.dbms_random.value(300,9999))                         sal,
            round(SYS.dbms_random.value(1,6)) * 100                        comm,
            round(SYS.dbms_random.value(1,4)) * 10                         deptno
     FROM DUAL
    CONNECT BY LEVEL < 1000000;

    這里有一個局限,原本的emp表mgr列reference empno列。上面新創(chuàng)建的emp_new中失去了這個constraint. 這點可以從Oracle SQL Developer中看到。
    emp表:
    with_constrant.png
    emp_new表:
    no_constrant.png
    下面就開始測試sql了:
    1. 先比較一下加primary key前后的結果:
    select * from emp_new where empno=1;
    加primary key constraint之前運行0.023秒。 加了primary key constraint之后0.001秒。加primary key constraint在100萬條數(shù)據(jù)上大約花費4秒鐘。
    2. where子句 vs. having子句
    select deptno, avg(sal) from emp_new group by deptno having deptno != 10 and deptno != 20;
    0.24秒
    select deptno, avg(sal) from emp_new where deptno != 10 and deptno != 20 group by deptno ;
    0.16秒
    所以having中的條件一般用于對一些集合函數(shù)的比較,如count()等,除此之外,一般條件應該寫在where子句中。

    3. 減少對表的查詢
    update emp_new set sal=(select max(sal) from emp_new), comm=(select max(comm) from emp_new) where empno=1237;
    0.11秒左右
    update emp_new set (sal, comm) =(select max(sal), max(comm) from emp_new) where empno=1224;
    0.07秒到0.08秒之間

    注意:以上三個測試都只fetch前50條數(shù)據(jù)。

    4. 傳說中用exists替代in通常可提高查詢效率, not exists 也比not in 快。
    先生成dept_new表:
    create table dept_new
    as
    select level                                                          deptno,
           SYS.dbms_random.String(
    'u', SYS.dbms_random.value(3,10))       dname,
           SYS.dbms_random.String(
    'u', SYS.dbms_random.value(3,9))        loc
    FROM DUAL
    CONNECT 
    BY LEVEL < 10000;
    實際測試中,無論是執(zhí)行計劃還是實際測試的速度都是基本一致的。
    第一組
    select * from emp_new e where e.empno > 986000 and e.deptno in (select d.deptno from dept_new d where d.loc='AYDN') select * from emp_new e where empno > 986000 and exists (select * from dept_new d where d.deptno = e.deptno and d.loc='AYDN') 第二組 select e.empno from emp_new e where e.empno > 996000 and not exists (select 1 from dept_new d where d.deptno = e.deptno and loc like 'A%') select e.empno from emp_new e where e.empno > 996000 and e.deptno not in (select d.deptno from dept_new d where loc like 'A%')

    這篇文字主要參考兩篇文章:
    Oracle sql  性能優(yōu)化調整: http://wenku.baidu.com/view/571cddd4195f312b3169a507 




    posted on 2013-03-31 21:49 人在江湖 閱讀(3138) 評論(0)  編輯  收藏 所屬分類: java
    主站蜘蛛池模板: 久久久久成人精品免费播放动漫| 美女被cao网站免费看在线看| 亚洲精品久久久www | 亚洲妇女熟BBW| 免费播放春色aⅴ视频| 曰批全过程免费视频在线观看无码| 亚洲综合日韩中文字幕v在线 | 性感美女视频免费网站午夜| EEUSS影院WWW在线观看免费| 亚洲精品影院久久久久久| 免费在线观看亚洲| 57pao一国产成永久免费| 苍井空亚洲精品AA片在线播放 | 免费看美女被靠到爽的视频| 在线观看免费视频一区| 亚洲综合无码一区二区痴汉| 亚洲av综合色区| 免费在线观看亚洲| 综合在线免费视频| 免费的全黄一级录像带| 国产成人+综合亚洲+天堂| 亚洲欧洲尹人香蕉综合| 久久精品国产亚洲Aⅴ蜜臀色欲| 天天看片天天爽_免费播放| 日本免费久久久久久久网站| 偷自拍亚洲视频在线观看99| 亚洲神级电影国语版| 亚洲精品字幕在线观看| 免费在线观看一级毛片| 野花高清在线观看免费完整版中文| 中文字幕乱码系列免费| 色九月亚洲综合网| 亚洲熟妇无码av另类vr影视| 亚洲人成亚洲精品| 亚洲成在人线av| 亚洲综合伊人久久综合| 亚洲成a人在线看天堂无码| 永久免费bbbbbb视频| 青青青国产在线观看免费| 久久久99精品免费观看| 免费人成激情视频在线观看冫|