Vincent.Chan‘s Blog

          常用鏈接

          統計

          積分與排名

          網站

          最新評論

          ORACLE SQL性能優化系列 (十四) 完結篇

          ORACLE SQL性能優化系列 (十四) 完結篇

          作者: black_snail

           

          關鍵字 ORACLE PERFORMANCE TUNING PL/SQL

          出處 http://www.dbasupport.com



          46. 連接多個掃描

          如果你對一個列和一組有限的值進行比較, 優化器可能執行多次掃描并對結果進行合并連接.

          舉例:

          SELECT *

          FROM LODGING

          WHERE MANAGER IN (‘BILL GATES','KEN MULLER');


          優化器可能將它轉換成以下形式

          SELECT *

          FROM LODGING

          WHERE MANAGER = ‘BILL GATES'

          OR MANAGER = 'KEN MULLER';


          當選擇執行路徑時, 優化器可能對每個條件采用LODGING$MANAGER上的索引范圍掃描. 返回的ROWID用來訪問LODGING表的記錄 (通過TABLE ACCESS BY ROWID 的方式). 最后兩組記錄以連接(CONCATENATION)的形式被組合成一個單一的集合.


          Explain Plan :


          SELECT STATEMENT Optimizer=CHOOSE

          CONCATENATION

          TABLE ACCESS (BY INDEX ROWID) OF LODGING

          INDEX (RANGE SCAN ) OF LODGING$MANAGER (NON-UNIQUE)

          TABLE ACCESS (BY INDEX ROWID) OF LODGING

          INDEX (RANGE SCAN ) OF LODGING$MANAGER (NON-UNIQUE)

          譯者按:

          本節和第37節似乎有矛盾之處.



          47. CBO下使用更具選擇性的索引

          基于成本的優化器(CBO, Cost-Based Optimizer)對索引的選擇性進行判斷來決定索引的使用是否能提高效率.

          如果索引有很高的選擇性, 那就是說對于每個不重復的索引鍵值,只對應數量很少的記錄.

          比如, 表中共有100條記錄而其中有80個不重復的索引鍵值. 這個索引的選擇性就是80/100 = 0.8 . 選擇性越高, 通過索引鍵值檢索出的記錄就越少.

          如果索引的選擇性很低, 檢索數據就需要大量的索引范圍查詢操作和ROWID 訪問表的

          操作. 也許會比全表掃描的效率更低.


          譯者按:

          下列經驗請參閱:

          a. 如果檢索數據量超過30%的表中記錄數.使用索引將沒有顯著的效率提高.

          b. 在特定情況下, 使用索引也許會比全表掃描慢, 但這是同一個數量級上的

          區別. 而通常情況下,使用索引比全表掃描要塊幾倍乃至幾千倍!



          48. 避免使用耗費資源的操作

          帶有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL語句會啟動SQL引擎

          執行耗費資源的排序(SORT)功能. DISTINCT需要一次排序操作, 而其他的至少需要執行兩次排序.

          例如,一個UNION查詢,其中每個查詢都帶有GROUP BY子句, GROUP BY會觸發嵌入排序(NESTED SORT) ; 這樣, 每個查詢需要執行一次排序, 然后在執行UNION時, 又一個唯一排序(SORT UNIQUE)操作被執行而且它只能在前面的嵌入排序結束后才能開始執行. 嵌入的排序的深度會大大影響查詢的效率.

          通常, 帶有UNION, MINUS , INTERSECT的SQL語句都可以用其他方式重寫.

          譯者按:

          如果你的數據庫的SORT_AREA_SIZE調配得好, 使用UNION , MINUS, INTERSECT也是可以考慮的, 畢竟它們的可讀性很強



          49. 優化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


          譯者按:

          本節和14節相同. 可略過.



          50. 使用日期

          當使用日期是,需要注意如果有超過5位小數加到日期上, 這個日期會進到下一天!


          例如:

          1.

          SELECT TO_DATE(‘01-JAN-93'+.99999)

          FROM DUAL;


          Returns:

          '01-JAN-93 23:59:59'

          2.

          SELECT TO_DATE(‘01-JAN-93'+.999999)

          FROM DUAL;


          Returns:

          '02-JAN-93 00:00:00'


          譯者按:

          雖然本節和SQL性能優化沒有關系, 但是作者的功力可見一斑



          51. 使用顯式的游標(CURSORs)

          使用隱式的游標,將會執行兩次操作. 第一次檢索記錄, 第二次檢查TOO MANY ROWS 這個exception . 而顯式游標不執行第二次操作.



          52. 優化EXPORT和IMPORT

          使用較大的BUFFER(比如10MB , 10,240,000)可以提高EXPORT和IMPORT的速度.

          ORACLE將盡可能地獲取你所指定的內存大小,即使在內存不滿足,也不會報錯.這個值至少要和表中最大的列相當,否則列值會被截斷.

          譯者按:

          可以肯定的是, 增加BUFFER會大大提高EXPORT , IMPORT的效率. (曾經碰到過一個CASE, 增加BUFFER后,IMPORT/EXPORT快了10倍!)

          作者可能犯了一個錯誤: “這個值至少要和表中最大的列相當,否則列值會被截斷. “

          其中最大的列也許是指最大的記錄大小.

          關于EXPORT/IMPORT的優化,CSDN論壇中有一些總結性的貼子,比如關于BUFFER參數, COMMIT參數等等, 詳情請查.



          53. 分離表和索引

          總是將你的表和索引建立在不同的表空間內(TABLESPACES). 決不要將不屬于ORACLE內部系統的對象存放到SYSTEM表空間里. 同時,確保數據表空間和索引表空間置于不同的硬盤上.


          譯者按:

          “同時,確保數據表空間和索引表空間置與不同的硬盤上.”可能改為如下更為準確 “同時,確保數據表空間和索引表空間置與不同的硬盤控制卡控制的硬盤上.”


          (全文完)

          作者:

          Black_Snail

          ligang1000@hotmail.com

          4/Sep/2003

          posted on 2006-02-25 22:34 Vincent.Chen 閱讀(200) 評論(0)  編輯  收藏 所屬分類: Database

          主站蜘蛛池模板: 儋州市| 成武县| 香河县| 澄城县| 威信县| 临颍县| 浠水县| 渭源县| 丰县| 柳江县| 岢岚县| 宜春市| 离岛区| 五大连池市| 米易县| 武威市| 昆明市| 平泉县| 萍乡市| 郯城县| 石棉县| 延津县| 杭州市| 保定市| 柯坪县| 当雄县| 武宁县| 吕梁市| 基隆市| 玉屏| 金门县| 如东县| 成都市| 金昌市| 咸宁市| 罗甸县| 察哈| 彰化市| 家居| 长治市| 睢宁县|