利用oracle執行計劃機制 提高 查詢性能。
這是從快速生成執行計劃的角度來優化性能,適用多表查詢的情況,使用Optimizer hints可以手動指定多表的連接順序以及連接方式。
使用hints的缺點就是,必須要管理,檢查,控制額外的代碼。數據庫以及主機環境的變化可能導致hints過時或者可能有負面的影響。因此hints用在測試或開發環境中。
1 執行SQL語句前的準備工作
SQL語句進入oracle的庫緩存後,在該語句準備執行之前,將執行下列步驟:
1) 語法檢查:檢查SQL語句拼寫是否正確
2) 語義分析:覈實所有的與數據字典不一致的表和列的名字
3) 輪廓存儲檢查:檢查數據字典,以確定該SQL語句的輪廓是否已經存在
4) 生成執行計劃:使用基於成本的優化規則和數據字典中的統計表來決定最佳執行計劃
5) 建立二進制代碼:基於執行計劃,oracle生成二進制執行代碼
一旦爲執行準備好了SQL語句,以後的執行將很快發生,因爲oracle認爲同一個SQL語句,並且重用那些語句的執行。然而,對於生成特殊的SQL語句,或嵌入了文字變量的SQL語句的系統,SQL執行計劃的生成時間就很重要。對於連接很多表查詢,oracle需要花費大量的時間來檢測連接這些表的適當順序。
2 評估表的連接順序
在SQL語句的準備過程中,花費最多的步驟是生成執行計劃。當oracle評估表的連接順序時,它必須考慮的表之間所有可能的連接。如,6個表之間連接有720種可能的連接線路。當一個查詢中含有超過10個表的連接時,排列的問題將變得更爲顯著。
3 Optimizer_search_limit參數來設定限制
Optimizer_search_limit參數,可以指定被優化器用來評估的最大的連接組合數量。可以防止優化器消耗不定數量的時間來評估所有可能的連接組合。
例如: 有5個表連接的查詢將有 120(5的階乘)中可能的連接組合,因此如果optimizer_search_limit等於5(默認值),則優化器將評估所有的120中可能。Optimizer_search_limit參數也控制着調用帶*的連接提示的閾值,當查詢表中的表數目比optimizer_search_limit小時,帶*的提示將被優先考慮。
4 Optimizer_max_permutations
Optimizer_max_permutations定義了優化器所考慮數目組合數上限。且依賴於參數optimizer_search_limit。Optimizer_max_permutations的默認值是80,000.
一旦優化器停止評估表的連接組合,它將選擇成本最低的組合。
5 Optimizer hints—ordered
在Oracle解決連接順序的最好方法是手工指定表的連接順序。通常優先使用限制最嚴格的where子句來連接表。
如:在emp表的關聯查詢上強制執行了嵌套循環連接,使用ordered 提示直接最優化表的評估順序,最終它們表現在where子句上。
Select /*+ ordered use_nl(bonus) parallel(e,4)*/ e.ename, hiredate, b.comm,
From emp e, bonus b
Where e.name=b.name;
這個例子要求優化器按順序連接再from子句中指定的表。From子句中第一個表時驅動表,ordered 提示通常被用來與其它的提示聯合起來保證採用正確的順序連接多個表。
Ordered 表示依據from後面寫的表的順序來做連接。
Leading,也是指定表的連接順序,但是不是按照from後面的表順序,而是在leading中定義連接順序。
Hash join可以通過no_swap_join_inputs/swap_join_inputs 來強制控制build表。
如,想實現(T3 hash-join(T1 hash-join T2)) hash-Join T4:
Select /*+ ordered
Use_hash(t2)
Use_hash(t3)
Swap_join_inputs(t3)
Use_hash(t4)
No_swap_join_inputs(t4)
*/
* from t1, t2,t3,t4
使用leading實現:
Select /*+ leading(t1 t2 t3 t4)
Use_hash(t2)
User_hash(t3)
Swap_join_inputs(t3)
Use_hash(t4)
No_swap_join_inputs(t4)
*/ * from t3,t4,t1,t2 ----使用了leading,from後面的表順序可以任意寫
6 優化器提示(optimizer hints)
在SQL語句中使用優化器提示可以改變執行計劃。
優化器提示可以指導優化器使用特定的方法。
6.1 Hint概述
Hint是優化器的指令。
當書寫一個SQL語句的時候,你應該對相關的數據信息有一些瞭解,但是優化器卻是沒有的。Hints使你可以做本該優化器做的決定。
在一個測試或開發環境中,hints被用來測試按照一個指定訪問路徑的性能。比如,你可能知道某個index對某個查詢更具有可選擇性。在這種情形下,你可以使用hints指導優化器使用一個更好的執行計劃。
使用hints的缺點就是,必須要管理,檢查,控制額外的代碼。數據庫以及主機環境的變化可能導致hints過時或者可能有負面的影響。因此,hints用於測試,使用其它方式管理SQL執行計劃,比如 SQL Tuning advisor 和SQL Plan baselines.
Oracle支持60多個hints,它們可能有0個或多個參數。
Hints必須出現在這些關鍵字之後:
Select,update,insert,merge,delete
比如:
Hints指導優化器使用 查詢出employee 表的前10行花銷最小的 執行計劃:
Select /*+ first_rows(10) */ * from employee;
6.2 Hints類型
6.2.1 單表hints
單表hints, 作用在一個指定的表或視圖上。Index 、use_nl就是單表hints
注意: use_nl(t1 t2)不是多表hints,只是 use_nl(t1) and use_nl(t2) 的簡寫。
6.2.2 多表hints
可以指定一個或多個表或視圖。Leading 就是多表hints.
6.2.3 查詢塊(query block)
查詢塊hint作用在單個查詢塊。比如:STAR_TRANSFORMATION 、 UNNEST
6.2.4 語句(statement)
對整個SQL 語句應用。比如:ALL_ROWS
6.3 Hints 類別
6.3.1 hints for join orders
如leading、ordered
6.3.2 hints for join operations
如:use_NL 、no_use_nl、use_nl_with_index, use_merge, no_user_merge
User_hash, no_use_hash
6.3.3 hints for parallel execution
parallel , no_parallel, parallel_index ,no_parallel_index
pq_distribute
6.3.4 hints for querytransformations
rewrite, merge, unnest, use_concat,no_expand
6.3.5 hints for access paths
full, cluster, hash, index,index_join,index_ffs
6.3.6 hints for optimizationapproaches and goals
如ALL_ROWS, FIRST_ROWS
7 參考資料
利用/*+Ordered*/提高查詢性能
http://blog.csdn.net/u011631923/article/details/14127249
oracle hint中ordered 和leading原理很好的帖子
http://blog.itpub.net/13918611/viewspace-1254731/
瞭解如何利用ordered,use_nl(),leading(),index()進行調優
http://blog.itpub.net/13129975/viewspace-627390/