Oracle 優化 ---學習

Oracle 優化

1.SQL語句解析:

       從後面往前(從右到左)的解析順序:  select  id from t1,t2,.......tn      tn先解析,解析完tn再解析tn-1,合併tn與tn-1數據,再解析tn-2,所以記錄最少的表應該放到最後,即基表

2.多表查詢,交叉表作爲基表

     EMP表描述了LOCATION表和CATEGORY表的交集

    a.低效  

n        SELECT *  FROM EMP E , LOCATION L , CATEGORY C  WHERE E.CAT_NO = C.CAT_NO  AND E.LOCN = L.LOCN
                                                                                                                    AND E.EMP_NO BETWEEN 1000 AND 2000
![endif]-->!--[if>       b.高效         
        SELECT * FROM LOCATION L , CATEGORY C,  EMP E WHERE E.EMP_NO BETWEEN 1000 AND 2000
                                                     AND E.CAT_NO = C.CAT_NO  AND E.LOCN = L.LOCN
   3.Where 後過濾條件           
        ORACLE採用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他WHERE條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾.
        a.低效
         SELECT * FROM EMP E  WHERE SAL > 50000 AND JOB = ‘MANAGER'
                                                              AND 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO);
         b.高效
         SELECT * FROM EMP E WHERE 25 <(SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO);
                                                             AND SAL>50000 AND JOB = 'MANAGER';
   4 select * from table
          * 效率極低,*要轉換成所有的列名,通過數據字典來實現,消耗更多的時間
  5 SQL執行
       ORACLE在內部執行了許多工作: 解析SQL語句, 估算索引的利用率, 綁定變量 , 讀數據塊等等. 由此可見, 減少訪問數據庫的次數 , 就能實際上減少ORACLE的工作量.
        a.低效
            SELECT EMP_NAME , SALARY , GRADE FROM EMP WHERE EMP_NO = 342;
           SELECT EMP_NAME , SALARY , GRADE FROM EMP WHERE EMP_NO = 291;

        b.次低效(使用遊標)
        c.高效
           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;
   6  HAVING和WHERE   GROUP+HAVING < WHERE +GROUP
      避免使用HAVING子句, HAVING 只會在檢索出所有記錄之後纔對結果集進行過濾. 這個處理需要排序,總計等操作. 如果能通過WHERE子句限制記錄的數目,那就能減少這方面的開銷
             a.低效
              SELECT REGION,AVG(LOG_SIZE) FROM LOCATION GROUP BY REGION HAVING REGION REGION != ‘SYDNEY' AND REGION != ‘PERTH'
             b.高效
             SELECT REGION,AVG(LOG_SIZE) FROM LOCATION WHERE REGION REGION != ‘SYDNEY' AND REGION != ‘PERTH' GROUP BY REGION
   7 子查詢的語句,減少對錶的查詢
     a.低效     
      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)

      b.高效
        SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) =
    ( SELECT TAB_NAME,DB_VER) FROM TAB_COLUMNS WHERE VERSION = 604)

     a1.低效
       UPDATE EMP SET EMP_CAT = (SELECT MAX(CATEGORY) FROM EMP_CATEGORIES),  SAL_RANGE = (SELECT MAX(SAL_RANGE) FROM EMP_CATEGORIES) WHERE EMP_DEPT = 0020;
     b1.高效
        UPDATE EMP SET (EMP_CAT, SAL_RANGE) = (SELECT MAX(CATEGORY) , MAX(SAL_RANGE) FROM EMP_CATEGORIES) WHERE EMP_DEPT = 0020;
    8.SQL鏈接多個表時,儘量用表的別名,減少解析時間及由Column引發的奇異(貌似與2NF衝突)
    9 EXITS(NOT EXITS) 高效於IN(NOT IN)
      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 * FROM DEPT WHERE
                                                                                                                     DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB')
      10 當提交一個包含一對多表信息(比如部門表和僱員表)的查詢時,避免在SELECT子句中使用DISTINCT. 一般可以考慮用EXIST替換
         a.低效
               SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D,EMP E WHERE D.DEPT_NO = E.DEPT_NO
         b.高效
            SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT * FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
         EXISTS 使查詢更爲迅速,因爲RDBMS核心模塊將在子查詢的條件一旦滿足後,立刻返回結果.



 


![endif]-->!--[if>![endif]-->!--[if>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章