Oracle提升SQL執行效率的三種方法 (修改了一下)sql
要提升SQL在Oracle裏的執行效率,優化應用的業務邏輯是最主要的,從技術層面來說Oracle也提供了一些方法,今天主要講3種:數據庫
Oracle提供了多種方法用於減小花在剖析OracleSQL表達式上的時間,在執行帶有大量執行計劃的複雜查詢時剖析過程會拖累系統的性能。如今咱們來簡要地看看這些方法中的幾種。oracle
一、使用ordered提示ide
Oracle必須花費大量的時間來剖析多表的合併,用以肯定表合併的最佳順序。若是SQL表達式涉及七個乃至更多的表合併,那麼有時就會須要超過30分鐘的時間來剖析,由於Oracle必須評估表合併全部可能的順序。八個表就會有40,000多種順序。Ordered這個提示(hint)和其餘的提示一塊兒使用可以產生合適的合併順序。函數
Ordered這個提示會要求列在SQL表達式FROM字句裏的表按照指定的順序進行合併,FROM字句裏的第一個表會指定驅動表格(drivingtable)。驅動表格應該是返回最小行數的表格。使用ordered提示會跳過很是耗時和耗資源的剖析操做,並加快Oracle SQL的執行。性能
Listing A以下:優化
如下是引用片斷:orm
Listing Ablog
select /*+ ordered use_nl(b) parallel(e, 4) */ e.ename, hiredate, b.comm索引
from emp e,bonus b
where e.ename = b.ename ;
ListingA裏是一個複雜查詢的例子,這個查詢被強制進行一個嵌套循環,從而與對emp表格進行的並行查詢合併。要注意,我已經使用ordered提示來引導Oracle去按照FROM子句所列出的順序來評估表格。
二、使用ordered_predicates
ordered_predicates提示在查詢的WHERE子句裏指定的,並被用來指定布爾判斷(Booleanpredicate)被評估的順序。在沒有ordered_predicates的狀況下,Oracle會使用下面這些步驟來評估SQL判斷的順序:
子查詢的評估先於外層WHERE子句裏的Boolean條件。
全部沒有內置函數或者子查詢的布爾條件都按照其在WHERE子句裏相反的順序進行評估,即最後一條判斷最早被評估。
每一個判斷都帶有內置函數的布爾判斷都依據其預計的評估值按遞增排列。
你可使用ordered_predicates提示來強制取代這些缺省的評估規則,那麼你WHERE子句裏的項目就會按照其在查詢裏出現的順序被評估。在查詢的WHERE子句裏使用了PL/SQL函數的狀況下,一般會使用ordered_predicates提示。若是你知道限制最多的判斷而且但願Oracle最早評估這些判斷的時候,在這種狀況下,它也是很是有用的。用法提示:你不能使用ordered_predicates提示來保存對索引鍵進行判斷評估的順序。
create table t1(v1,n1,n2) as select to_char(mod(rownum,20)),rownum,mod(rownum,20) from all_objects where rownum<=3000;
SQL> execute dbms_stats.gather_tabLE_stats('HR','T1');
SQL> select
2 v1,n2,n1
3 from t1
4 where v1=1
5 and n2=18
6 and n1=998
7 ;
no rows selected
Execution Plan
Plan hash value: 3617692013
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 10 | 4 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 1 | 10 | 4 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - filter("N1"=998 AND "N2"=18 AND TO_NUMBER("V1")=1)
SQL> select /*+ ordered_predicates */
2 v1,n2,n1
3 from t1
4 where v1=1
5 and n2=18
6 and n1=998
7 ;
no rows selected
Execution Plan
Plan hash value: 3617692013
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 48 | 4 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 1 | 48 | 4 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - filter(TO_NUMBER("V1")=1 AND "N2"=18 AND "N1"=998)
三、限制表格合併評估的數量
提升SQL剖析性能的最後一種方法是強制取代Oracle的一個參數,這個參數控制着在評估一個查詢的時候,基於消耗的優化器所評估的可能合併數量。
_optimizer_search_limit這個參數會指定表格合併組合的最大數量,後者將會在Oracle試圖肯定合併多表格最佳方式的時候被評估。這個參數有助於防止優化器花更多的時間來評估可能的合併順序,而不是把時間花在尋找最佳合併順序上。_optimizer_search_limit還控制着用於調用starjoin提示的闕值,當查詢裏的表格數量低於_optimizer_search_limit(其缺省的值是5)的時候,star提示就會被光顧。