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

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

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

    1.       用IN來替換OR
    下面的查詢可以被更有效率的語句替換:
    低效:
    SELECT field1, field1 FROM LOCATION
    WHERE LOC_ID = 10 OR     LOC_ID = 20 OR     LOC_ID = 30

    高效
    SELECT field1, field1 FROM LOCATION
    WHERE LOC_IN IN (10,20,30)    
    2.       連接多個掃描
    如果你對一個列和一組有限的值進行比較, 優化器可能執行多次掃描并對結果進行合并連接.
    舉例:
        SELECT * FROM LODGING
        WHERE MANAGER IN (‘BILL GATES’,’KEN MULLER’);
     
        優化器可能將它轉換成以下形式
        SELECT *  FROM LODGING
        WHERE MANAGER = ‘BILL GATES’
        OR MANAGER = ’KEN MULLER’;
    3.       優化GROUP BY
    提高GROUP BY 語句的效率, 可以通過將不需要的記錄在GROUP BY 之前過濾掉.下面兩個查詢返回相同結果但第二個明顯就快了許多.
    低效:
       SELECT JOB , AVG(SAL) FROM EMP
       GROUP JOB HAVING JOB = ‘PRESIDENT’OR JOB = ‘MANAGER’
     高效:
       SELECT JOB , AVG(SAL) FROM EMP
       WHERE JOB = ‘PRESIDENT’OR JOB = ‘MANAGER’
       GROUP JOB  
    4.       用>=替代>
    如果DEPTNO上有一個索引, 
    高效:
       SELECT *
       FROM EMP
       WHERE DEPTNO >=4
       
       低效:
       SELECT *
       FROM EMP
       WHERE DEPTNO >3

    5.       用表連接替換EXISTS
         通常來說 , 采用表連接的方式比EXISTS更有效率
          SELECT ENAME
          FROM EMP E
          WHERE EXISTS (SELECT ‘X’ 
                          FROM DEPT
                          WHERE DEPT_NO = E.DEPT_NO
                          AND DEPT_CAT = ‘A’);

         (更高效)
          SELECT ENAME
          FROM DEPT D,EMP E
          WHERE E.DEPT_NO = D.DEPT_NO
          AND DEPT_CAT = ‘A’ ; 
    6.       用EXISTS替換DISTINCT
    當提交一個包含一對多表信息(比如部門表和雇員表)的查詢時,避免在SELECT子句中使用DISTINCT. 一般可以考慮用EXIST替換 
    低效:
        SELECT DISTINCT DEPT_NO,DEPT_NAME
        FROM DEPT D,EMP E
        WHERE D.DEPT_NO = E.DEPT_NO
    高效:
        SELECT DEPT_NO,DEPT_NAME
        FROM DEPT D
        WHERE EXISTS ( SELECT ‘X’
                        FROM EMP E
                        WHERE E.DEPT_NO = D.DEPT_NO);

      EXISTS 使查詢更為迅速,因為RDBMS核心模塊將在子查詢的條件一旦滿足后,立刻返回結果.
    7.       使用表的別名(Alias)
    當在SQL語句中連接多個表時, 請使用表的別名并把別名前綴于每個Column上.這樣一來,就可以減少解析的時間并減少那些由Column歧義引起的語法錯誤.
    (譯者注: Column歧義指的是由于SQL中不同的表具有相同的Column名,當SQL語句中出現這個Column時,SQL解析器無法判斷這個Column的歸屬)

    8.       用EXISTS替代IN
    在許多基于基礎表的查詢中,為了滿足一個條件,往往需要對另一個表進行聯接.在這種情況下, 使用EXISTS(或NOT EXISTS)通常將提高查詢的效率.
    低效:
    SELECT * 
    FROM EMP (基礎表)
    WHERE EMPNO > 0
    AND DEPTNO IN (SELECT DEPTNO 
    FROM DEPT 
    WHERE LOC = ‘MELB’)
    高效: 
    SELECT * 
    FROM EMP (基礎表)
    WHERE EMPNO > 0
    AND EXISTS (SELECT ‘X’ 
    FROM DEPT 
    WHERE DEPT.DEPTNO = EMP.DEPTNO
    AND LOC = ‘MELB’)
     (譯者按: 相對來說,用NOT EXISTS替換NOT IN 將更顯著地提高效率,下一節中將指出)
    9.       用NOT EXISTS替代NOT IN
    在子查詢中,NOT IN子句將執行一個內部的排序和合并. 無論在哪種情況下,NOT IN都是最低效的 (因為它對子查詢中的表執行了一個全表遍歷).  為了避免使用NOT IN ,我們可以把它改寫成外連接(Outer Joins)或NOT EXISTS.
    例如:
    SELECT …
    FROM EMP
    WHERE DEPT_NO NOT IN (SELECT DEPT_NO 
                             FROM DEPT 
                             WHERE DEPT_CAT=’A’);
    為了提高效率.改寫為:
    (方法一: 高效)
    SELECT ….
    FROM EMP A,DEPT B
    WHERE A.DEPT_NO = B.DEPT(+)
    AND B.DEPT_NO IS NULL
    AND B.DEPT_CAT(+) = ‘A’
    (方法二: 最高效)
    SELECT ….
    FROM EMP E
    WHERE NOT EXISTS (SELECT ‘X’ 
                        FROM DEPT D
                        WHERE D.DEPT_NO = E.DEPT_NO
                        AND DEPT_CAT = ‘A’);
    10.       減少對表的查詢
    在含有子查詢的SQL語句中,要特別注意減少對表的查詢.
    例如: 
         低效
              SELECT TAB_NAME
              FROM TABLES
              WHERE TAB_NAME = ( SELECT TAB_NAME 
                                    FROM TAB_COLUMNS
                                    WHERE VERSION = 604)
              AND DB_VER= ( SELECT DB_VER 
                               FROM TAB_COLUMNS
                               WHERE VERSION = 604)
         高效
              SELECT TAB_NAME
              FROM TABLES
              WHERE  (TAB_NAME,DB_VER)
     = ( SELECT TAB_NAME,DB_VER) 
                       FROM TAB_COLUMNS
                       WHERE VERSION = 604)
         Update 多個Column 例子:
         低效:
               UPDATE EMP
               SET EMP_CAT = (SELECT MAX(CATEGORY) FROM EMP_CATEGORIES),
                  SAL_RANGE = (SELECT MAX(SAL_RANGE) FROM EMP_CATEGORIES)
               WHERE EMP_DEPT = 0020;
         高效:
               UPDATE EMP
               SET (EMP_CAT, SAL_RANGE) 
    = (SELECT MAX(CATEGORY) , MAX(SAL_RANGE)
     FROM EMP_CATEGORIES)
               WHERE EMP_DEPT = 0020;
    11. 在Oracle快速進行數據行存在性檢查
    只檢索一個啟示就可以判斷主鍵是否能與外鍵相配,這比Count(*)方法快得多,例如: 
    SQL Using Count(*) 
        SELECT Count(*) INTO :ll_Count
           FROM ORDER
           WHERE PROD_ID = :ls_CheckProd
           USING SQLCA;
        
        IF ll_Count > 0 THEN // Cannot delete product 
    SQL Using ROWNUM
       SELECT ORDER_ID INTO :ll_OrderID
           FROM ORDER
           WHERE PROD_ID = :ls_CheckProd
              AND ROWNUM < 2
           USING SQLCA;

        IF SQLCA.SQLNRows <> 0 THEN // cannot delete product
    12 使用%TYPE、%ROWTYPE方式聲明變量
      程序設計中常常要通過變量來實現程序間的數據傳遞,即將表中數據賦值給變量,或是把變量值插入到表中。而要完成這些操作的前提就是,表中數據與變量類型要一致。然而在實際中,表中數據或類型、或寬度有時要變化,一旦變化,就必須去修改程序中的變量聲明部分,否則程序將不能正常運行。為了減少這部分程序的修改,編程時使用%TYPE、%ROWTYPE方式聲明變量,使變量聲明的類型與表中的保持同步,隨表的變化而變化,這樣的程序在一定程度上具有更強的通用性。
    13.       使用DECODE函數來減少處理時間
    使用DECODE函數可以避免重復掃描相同記錄或重復連接相同的表.
    例如:
       SELECT COUNT(*),SUM(SAL)
       FROM EMP
       WHERE DEPT_NO = 0020
       AND ENAME LIKE ‘SMITH%’;

       SELECT COUNT(*),SUM(SAL)
       FROM EMP
       WHERE DEPT_NO = 0030
       AND ENAME LIKE ‘SMITH%’;

    你可以用DECODE函數高效地得到相同結果

    SELECT COUNT(DECODE(DEPT_NO,0020,’X’,NULL)) D0020_COUNT,
            COUNT(DECODE(DEPT_NO,0030,’X’,NULL)) D0030_COUNT,
            SUM(DECODE(DEPT_NO,0020,SAL,NULL)) D0020_SAL,
            SUM(DECODE(DEPT_NO,0030,SAL,NULL)) D0030_SAL
    FROM EMP WHERE ENAME LIKE ‘SMITH%’;

    類似的,DECODE函數也可以運用于GROUP BY 和ORDER BY子句中.
    14.       盡量多使用COMMIT
    只要有可能,在程序中盡量多使用COMMIT, 這樣程序的性能得到提高,需求也會因為COMMIT所釋放的資源而減少:
     COMMIT所釋放的資源:
    a.       回滾段上用于恢復數據的信息.
    b.       被程序語句獲得的鎖
    c.       redo log buffer 中的空間
    d.       ORACLE為管理上述3種資源中的內部花費
    15.       整合簡單,無關聯的數據庫訪問
    如果你有幾個簡單的數據庫查詢語句,你可以把它們整合到一個查詢中(即使它們之間沒有關系)
    例如:

    SELECT NAME 
    FROM EMP 
    WHERE EMP_NO = 1234;

    SELECT NAME 
    FROM DPT
    WHERE DPT_NO = 10 ;

    SELECT NAME 
    FROM CAT
    WHERE CAT_TYPE = ‘RD’;

    上面的3個查詢可以被合并成一個:

    SELECT E.NAME , D.NAME , C.NAME
    FROM CAT C , DPT D , EMP E,DUAL X
    WHERE NVL(‘X’,X.DUMMY) = NVL(‘X’,E.ROWID(+))
    AND NVL(‘X’,X.DUMMY) = NVL(‘X’,D.ROWID(+))
    AND NVL(‘X’,X.DUMMY) = NVL(‘X’,C.ROWID(+))
    AND E.EMP_NO(+) = 1234
    AND D.DEPT_NO(+) = 10
    AND C.CAT_TYPE(+) = ‘RD’; 
    16.       WHERE子句中的連接順序.
    ORACLE采用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他WHERE條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾.
    例如:
    (低效,執行時間156.3秒)
    SELECT … 
    FROM EMP E
    WHERE  SAL > 50000
    AND    JOB = ‘MANAGER’
    AND    25 < (SELECT COUNT(*) FROM EMP
                 WHERE MGR=E.EMPNO);

    (高效,執行時間10.6秒)
    SELECT … 
    FROM EMP E
    WHERE 25 < (SELECT COUNT(*) FROM EMP
                 WHERE MGR=E.EMPNO)
    AND    SAL > 50000
    AND    JOB = ‘MANAGER’;
    17.     減少訪問數據庫的次數
    當執行每條SQL語句時, ORACLE在內部執行了許多工作: 解析SQL語句, 估算索引的利用率, 綁定變量 , 讀數據塊等等. 由此可見, 減少訪問數據庫的次數 , 就能實際上減少ORACLE的工作量.

    例如,
        以下有三種方法可以檢索出雇員號等于0342或0291的職員.

    方法1 (最低效)
        SELECT EMP_NAME , SALARY , GRADE
        FROM EMP 
        WHERE EMP_NO = 342;
         
        SELECT EMP_NAME , SALARY , GRADE
        FROM EMP 
        WHERE EMP_NO = 291;

    方法2 (次低效)
        
        DECLARE 
            CURSOR C1 (E_NO NUMBER) IS 
            SELECT EMP_NAME,SALARY,GRADE
            FROM EMP 
            WHERE EMP_NO = E_NO;
        BEGIN 
            OPEN C1(342);
            FETCH C1 INTO …,..,.. ;
            …..
            OPEN C1(291);
           FETCH C1 INTO …,..,.. ;
             CLOSE C1;
          END;

    方法3 (高效)

        SELECT A.EMP_NAME , A.SALARY , A.GRADE,
                B.EMP_NAME , B.SALARY , B.GRADE
        FROM EMP A,EMP B
        WHERE A.EMP_NO = 342
        AND   B.EMP_NO = 291; 
    posted on 2008-09-20 15:32 李威威 閱讀(161) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
     
    主站蜘蛛池模板: 99精品热线在线观看免费视频| 春暖花开亚洲性无区一区二区| 久别的草原电视剧免费观看| 亚洲香蕉成人AV网站在线观看| 人成免费在线视频| 国产成人99久久亚洲综合精品| www免费黄色网| 国产亚洲精品成人a v小说| 精品一区二区三区高清免费观看| 亚洲成a人一区二区三区| 免费国产va在线观看| 亚洲一区二区高清| 日韩免费高清播放器| 亚洲成a人片在线观看中文动漫| 99xxoo视频在线永久免费观看| 亚洲高清日韩精品第一区| 男女免费观看在线爽爽爽视频 | 美女免费视频一区二区三区| 国产免费卡一卡三卡乱码| jzzijzzij在线观看亚洲熟妇| 四虎影在线永久免费四虎地址8848aa | 一级黄色毛片免费看| 久久久久亚洲AV综合波多野结衣| 九九99热免费最新版| 婷婷久久久亚洲欧洲日产国码AV | 亚洲欧洲日韩在线电影| 又粗又大又黑又长的免费视频| 噜噜噜亚洲色成人网站∨| 一级特黄色毛片免费看| 亚洲第一精品在线视频| 69视频在线是免费观看| 亚洲a级在线观看| 国偷自产一区二区免费视频| 久久99国产亚洲高清观看首页| 免费看搞黄视频网站| 亚洲精品综合久久中文字幕| 中文字幕人成无码免费视频| 亚洲欧美日韩综合俺去了| 亚洲第一页日韩专区| 中文字幕在线成人免费看| 亚洲视频一区在线|