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

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

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

    人在江湖

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      82 Posts :: 10 Stories :: 169 Comments :: 0 Trackbacks
    這篇文字主要討論sql的一般編寫原則。下一篇討論根據執行計劃進行調優的話題。
    網上這類文章很多,但往往只是給出結論,比如,這樣寫sql會比那樣寫sql效率更高。閱讀者如果打算打開數據庫自己做一遍實驗,看看效率差異到底有多少,需要自己造數據,還是比較麻煩。這篇文字會把DDL和DML以及sql的執行時間都寫出來,一方面給一個更直觀的印象,另一方面方便閱讀者自己實驗。
    以Oracle為實驗用數據庫,使用著名的emp表。安裝oracle數據庫之后,scott用戶的密碼是tiger. 在他的schema下有幾張sample表,很多sql教程都以這幾張表為基礎. 據說,熟悉oracle數據庫的人提到smith這個人名,就能聯想起sample表中他的工作是clerk. emp表就是sample表之一。這張表原始數據只有14行,為了體現不同sql性能上的差異,我們需要多填充一些數據進去。作為填充數據的預備知識,我們可以看一下如何生成一系列從小到大的id:
    SELECT ROWNUM
    FROM DUAL
    CONNECT BY LEVEL < 10000;
    填充隨機數據可以借助于dbms_random包,不想覆蓋已有的表,所以新創建一個表結構基本一樣的: 
    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列。上面新創建的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萬條數據上大約花費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中的條件一般用于對一些集合函數的比較,如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條數據。

    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;
    實際測試中,無論是執行計劃還是實際測試的速度都是基本一致的。
    第一組
    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  性能優化調整: http://wenku.baidu.com/view/571cddd4195f312b3169a507 




    posted on 2013-03-31 21:49 人在江湖 閱讀(3138) 評論(0)  編輯  收藏 所屬分類: java
    主站蜘蛛池模板: 91嫩草国产在线观看免费| 亚洲精品无码你懂的网站| 一区视频免费观看| 亚洲免费二区三区| 国产av无码专区亚洲av桃花庵| 性做久久久久免费观看| 91精品啪在线观看国产线免费| 一区二区视频免费观看| 亚洲AV日韩AV一区二区三曲| 亚洲综合在线成人一区| 国产亚洲综合网曝门系列| 免费国产成人高清视频网站| 国产精品久久免费| 嫩草成人永久免费观看| 日韩a毛片免费观看| 亚洲国产精品18久久久久久| 亚洲黄色在线视频| 亚洲高清国产AV拍精品青青草原| 亚洲天堂在线视频| 日日AV拍夜夜添久久免费| 国产成人免费爽爽爽视频| 日本免费xxxx| 免费视频成人片在线观看| 国产在线观看无码免费视频| 一区二区三区在线免费| 男女啪啪免费体验区| 蜜芽亚洲av无码一区二区三区 | 国产成人综合亚洲| 亚洲色成人网站WWW永久四虎| 亚洲国产精品综合久久2007| 久久精品国产亚洲一区二区| 亚洲熟伦熟女新五十路熟妇| 亚洲XX00视频| 免费A级毛片无码久久版| 在线看片无码永久免费aⅴ| 免费看大美女大黄大色| 免费看a级黄色片| 国产猛烈高潮尖叫视频免费| 免费看无码自慰一区二区| 四虎永久精品免费观看| 免费A级毛片无码A∨男男|