用智能優化限制提高Oracle數據庫性能

發表于:2008-02-22來源:作者:點擊數: 標簽:
Oracle SQL 運行時間的最主要的組成部分是花在為執行準備新的SQL語句上的時間。不過,如果了解了可執行計劃產生的內在機制,你就可以控制Oracle花費在評估表的連接順序的時間,并在總體上提高查詢的 性能 。 準備為執行提供的SQL語句 在一個SQL語句進入Oracle
Oracle SQL運行時間的最主要的組成部分是花在為執行準備新的SQL語句上的時間。不過,如果了解了可執行計劃產生的內在機制,你就可以控制Oracle花費在評估表的連接順序的時間,并在總體上提高查詢的性能。

  準備為執行提供的SQL語句

  在一個SQL語句進入Oracle庫的cache之后、而真正被執行之前,將會依次發生如下事件:

  語法檢查——檢查該SQL語句的拼寫和詞序是否正確。

  語義解析——Oracle根據數據詞典(data dictionary)來驗證所有的表格(table)和列(column)。

  已保存綱要檢查——Oracle檢查詞典以確認對應該SQL語句是否已存在已保存的綱要(Stored Outline)。

  產生執行計劃——Oracle根據一種罰值(cost-based)優化算法和數據詞典中的統計數據來決定如何生成最優執行計劃。

  產生二進制代碼——Oracle在執行計劃的基礎上生成可執行的二進制代碼。

  一旦開始準備執行SQL語句,上述的過程很快就會執行,這是因為Oracle可以識別出同樣的SQL語句并對同樣的SQL語句重復使用對應的可執行代碼。然而,對產生ad hoc SQL的系統以及SQL中嵌入文本值(literal value)的情況,SQL執行計劃的生成時間就會變得相當長,而且以前的執行計劃也常常不能被再次利用。對那些牽涉到許多表格的查詢,Oracle可能要花上很長的時間來決定把連接這些表格的順序。

  評估連接表格的順序

  生成可執行計劃的時間往往是SQL的準備過程中最大的開銷組成部分,尤其是在處理有多個表的連接的查詢的情況下。當Oracle評估表的連接順序時,它必須考慮每一種可能的排序。例如,當有六個表格需要連接時,Oracle需要考慮720種(6的排列數,即6×5×4×3×2×1=720)可能的連接排序。當需要連接的表的數量超過10時,這個排列問題將變得非常突出:如果需要連接的表格有15個,那么需要考慮的可能的查詢排列順序超過一萬億種(精確值為1,307,674,368,000)。

  在optimizer_search_limit參數中設置限制

  你可以通過optimizer_search_limit參數來控制上述問題的發生,該參數用來指定優化器評估的表格連接順序的最大數目。利用這個參數,就可以防止優化器在評估所有可能的表格連接順序中所花費的多余時間。如果查詢中的表的數量少于或者等于optimizer_search_limit,那么優化器檢查所有的可能表的連接方式。

  例如,涉及了五個表的查詢一共有120種(5?。?×4×3×2×1=120)可能的連接順序,所以如果參數optimizer_search_limit的值設置為5(默認值),那么優化器就會考慮所有的這120種可能的連接順序。optimizer_search_limit參數還用來控制啟動開始連接指示(star join hint)的閾值。當查詢所涉及的表格數量少于參數optimizer_search_limit的設定值,開始連接指示將被設置。

  另一個工具:optimizer_max_permutations參數

  optimizer_max_permutations初始參數用來設定優化器優化范圍的上界(即最多考慮多少種表格連接順序),它依賴于初始參數  optimizer_search_limit。參數optimizer_max_permutations的默認值為8000。

  參數optimizer_search_limit 和optimizer_max_permutations一同用來設置優化器所考慮的排列數的上限。優化器不斷的產生可能的表的連接的排列,直到排列數達到參數optimizer_search_limit或者optimizer_max_permutations為止。一旦優化器停止產生新的可能連接排列,它將會從中選擇出耗費最小的排列。

  用已排序指示來指定一種連接排序

  你可以設定優化器評估的排列數的上限。但是對復雜的情況下,即使允許的排列數很大,優化器也很可能在遠遠沒有找到一個比較合適的排列之間就已經停止優化了。你不妨回頭看看我前面舉的那個例子(15個需要連接的表有超過一萬億種排列)。如果設定優化器考慮80,000種排列,那么這僅僅考慮了所有可能性的0.000006%,優化器極可能沒有達到最佳的排列。

  在Oracle SQL中解決這個問題的最好方法就是手工指定一種表格連接順序。這里需要遵循的大原則就是表格連接順序應該使得查詢計劃盡快得以建立,通常在SQL語句中使用WHERE限制子句。

  下面以一個對名為emp的表格的并行查詢為例,例子中的代碼強制查詢計劃執行一個嵌套循環連接(nested loop join)。注意,我使用了已排序指示來引導優化器來評估WHERE子句中給出的表格的連接順序。

    select /*+ ordered use_nl(bonus) parallel(e, 4) */   e.ename,   hiredate,   b.comm.   from   emp e,   bonus b   where   e.ename = b.ename   ;

原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97