Oracle10g常見HINT的用法

Oracle10g常見HINT的用法

語法:
提示裏不區分大小寫,多個提示用空格分開,如:select/*+hint1(tab1)hint2(TAB1idx1)*/col1,col2fromtab1wherecol1='xxx';
如果表使用了別名,那麼提示裏也必須使用別名,如:select/*+hint1(t1)*/col1,col2fromtab1t1wherecol1='xxx';

在SQL優化過程中常見HINT的用法(前10個比較常用,前3個最常用):

1./*+INDEX*/和/*+INDEX(TABLEINDEX1,index2)*/和/*+INDEX(tab1.col1tab2.col2)*/和/*+NO_INDEX*/和/*+NO_INDEX(TABLEINDEX1,index2)*/
表明對錶選擇索引的掃描方法.第一種不指定索引名是讓oracle對錶中可用索引比較並選擇某個最佳索引;第二種是指定索引名且可指定多個索引;第三種是10g開始有的,指定列名,且表名可不用別名;第四種即全表掃描;第五種表示禁用某個索引,特別適合於準備刪除某個索引前的評估操作.如果同時使用了INDEX和NO_INDEX則兩個提示都會被忽略掉.
例如:SELECT/*+INDEX(BSEMPMSSEX_INDEX)USESEX_INDEXBECAUSETHEREAREFEWMALEBSEMPMS*/FROMBSEMPMSWHERESEX='M';

2./*+ORDERED*/
FROM子句中默認最後一個表是驅動表,ORDERED將from子句中第一個表作爲驅動表.特別適合於多表連接非常慢時嘗試.
例如:SELECT/*+ORDERED*/A.COL1,B.COL2,C.COL3FROMTABLE1A,TABLE2B,TABLE3CWHEREA.COL1=B.COL1ANDB.COL1=C.COL1;

3./*+PARALLEL(table1,DEGREE)*/和/*+NO_PARALLEL(table1)*/
該提示會將需要執行全表掃描的查詢分成多個部分(並行度)執行,然後在不同的操作系統進程中處理每個部分.該提示還可用於DML語句.如果SQL裏還有排序操作,進程數會翻倍,此外還有一個一個負責組合這些部分的進程,如下面的例子會產生9個進程.如果在提示中沒有指定DEGREE,那麼就會使用創建表時的默認值.該提示在默認情況下會使用APPEND提示.NO_PARALLEL是禁止並行操作,否則語句會使用由於定義了並行對象而產生的並行處理.
例如:select/*+PARALLEL(tab_test,4)*/col1,col2fromtab_testorderbycol2;

4./*+FIRST_ROWS*/和/*+FIRST_ROWS(n)*/
表示用最快速度獲得第1/n行,獲得最佳響應時間,使資源消耗最小化.
在update和delete語句裏會被忽略,使用分組語句如groupby/distinct/intersect/minus/union時也會被忽略.
例如:SELECT/*+FIRST_ROWS*/EMP_NO,EMP_NAM,DAT_INFROMBSEMPMSWHEREEMP_NO='SCOTT';

5./*+RULE*/
表明對語句塊選擇基於規則的優化方法.
例如:SELECT/*+RULE*/EMP_NO,EMP_NAM,DAT_INFROMBSEMPMSWHEREEMP_NO='SCOTT';

6./*+FULL(TABLE)*/
表明對錶選擇全局掃描的方法.
例如:SELECT/*+FULL(A)*/EMP_NO,EMP_NAMFROMBSEMPMSAWHEREEMP_NO='SCOTT';

7./*+LEADING(TABLE)*/
類似於ORDERED提示,將指定的表作爲連接次序中的驅動表.

8./*+USE_NL(TABLE1,TABLE2)*/
將指定表與嵌套的連接的行源進行連接,以最快速度返回第一行再連接,與USE_MERGE剛好相反.
例如:SELECT/*+ORDEREDUSE_NL(BSEMPMS)*/BSDPTMS.DPT_NO,BSEMPMS.EMP_NO,BSEMPMS.EMP_NAMFROMBSEMPMS,BSDPTMSWHEREBSEMPMS.DPT_NO=BSDPTMS.DPT_NO;

9./*+APPEND*/和/*+NOAPPEND*/
直接插入到表的最後,該提示不會檢查當前是否有插入操作所需的塊空間而是直接添加到新塊中,所以可以提高速度.當然也會浪費些空間,因爲它不會使用那些做了delete操作的塊空間.NOAPPEND提示則相反,所以會取消PARALLEL提示的默認APPEND提示.
例如:insert/*+append*/intotest1select*fromtest4;
insert/*+parallel(test1)noappend*/intotest1select*fromtest4;

10./*+USE_HASH(TABLE1,table2)*/
將指定的表與其它行源通過哈希連接方式連接起來.爲較大的結果集提供最佳響應時間.類似於在連接表的結果中遍歷每個表上每個結果的嵌套循環,指定的hash表將被放入內存,所以需要有足夠的內存(hash_area_size或pga_aggregate_target)才能保證語句正確執行,否則將在磁盤裏進行.
例如:SELECT/*+USE_HASH(BSEMPMS,BSDPTMS)*/*FROMBSEMPMS,BSDPTMSWHEREBSEMPMS.DPT_NO=BSDPTMS.DPT_NO;

----------------------------------------------------------------------------------------------------

11./*+USE_MERGE(TABLE)*/
將指定的表與其它行源通過合併排序連接方式連接起來.特別適合於那種在多個表大量行上進行集合操作的查詢,它會將指定表檢索到的的所有行排序後再被合併,與USE_NL剛好相反.
例如:SELECT/*+USE_MERGE(BSEMPMS,BSDPTMS)*/*FROMBSEMPMS,BSDPTMSWHEREBSEMPMS.DPT_NO=BSDPTMS.DPT_NO;

12./*+ALL_ROWS*/
表明對語句塊選擇基於開銷的優化方法,並獲得最佳吞吐量,使資源消耗最小化.可能會限制某些索引的使用.
例如:SELECT/*+ALL+_ROWS*/EMP_NO,EMP_NAM,DAT_INFROMBSEMPMSWHEREEMP_NO='SCOTT';

13./*+CLUSTER(TABLE)*/
提示明確表明對指定表選擇簇掃描的訪問方法.如果經常訪問連接表但很少修改它,那就使用集羣提示.
例如:SELECT/*+CLUSTER*/BSEMPMS.EMP_NO,DPT_NOFROMBSEMPMS,BSDPTMSWHEREDPT_NO='TEC304'ANDBSEMPMS.DPT_NO=BSDPTMS.DPT_NO;

14./*+INDEX_ASC(TABLEINDEX1,INDEX2)*/
表明對錶選擇索引升序的掃描方法.從8i開始,這個提示和INDEX提示功能一樣,因爲默認oracle就是按照升序掃描索引的,除非未來oracle還退出降序掃描索引.
例如:SELECT/*+INDEX_ASC(BSEMPMSPK_BSEMPMS)*/FROMBSEMPMSWHEREDPT_NO='SCOTT';

15./*+INDEX_COMBINE(TABLEINDEX1,INDEX2)*/
指定多個位圖索引,對於B樹索引則使用INDEX這個提示,如果INDEX_COMBINE中沒有提供作爲參數的索引,將選擇出位圖索引的布爾組合方式.
例如:SELECT/*+INDEX_COMBINE(BSEMPMSSAL_BMIHIREDATE_BMI)*/*FROMBSEMPMSWHERESAL<5000000ANDHIREDATE<SYSDATE;

16./*+INDEX_JOIN(TABLEINDEX1,INDEX2)*/
合併索引,所有數據都已經包含在這兩個索引裏,不會再去訪問表,比使用索引並通過rowid去掃描表要快5倍.
例如:SELECT/*+INDEX_JOIN(BSEMPMSSAL_HMIHIREDATE_BMI)*/SAL,HIREDATEFROMBSEMPMSWHERESAL<60000;

17./*+INDEX_DESC(TABLEINDEX1,INDEX2)*/
表明對錶選擇索引降序的掃描方法.
例如:SELECT/*+INDEX_DESC(BSEMPMSPK_BSEMPMS)*/FROMBSEMPMSWHEREDPT_NO='SCOTT';

18./*+INDEX_FFS(TABLEINDEX_NAME)*/
對指定的表執行快速全索引掃描,而不是全表掃描的辦法.要求要檢索的列都在索引裏,如果表有很多列時特別適用該提示.
例如:SELECT/*+INDEX_FFS(BSEMPMSIN_EMPNAM)*/*FROMBSEMPMSWHEREDPT_NO='TEC305';

19./*+NO_EXPAND*/
對於WHERE後面的OR或者IN-LIST的查詢語句,NO_EXPAND將阻止其基於優化器對其進行擴展,縮短解析時間.
例如:SELECT/*+NO_EXPAND*/*FROMBSEMPMSWHEREDPT_NO='TDC506'ANDSEX='M';

20./*+DRIVING_SITE(TABLE)*/
強制與ORACLE所選擇的位置不同的表進行查詢執行.特別適用於通過dblink連接的遠程表.
例如:SELECT/*+DRIVING_SITE(DEPT)*/*FROMBSEMPMS,[email protected]_NO=DEPT.DPT_NO;

21./*+CACHE(TABLE)*/和/*+NOCACHE(TABLE)*/
當進行全表掃描時,CACHE提示能夠將表全部緩存到內存中,這樣訪問同一個表的用戶可直接在內存中查找數據.比較適合數據量小但常被訪問的表,也可以建表時指定cache選項這樣在第一次訪問時就可以對其緩存.NOCACHE則表示對已經指定了CACHE選項的表不進行緩存.
例如:SELECT/*+FULL(BSEMPMS)CAHE(BSEMPMS)*/EMP_NAMFROMBSEMPMS;

22./*+PUSH_SUBQ*/
當SQL裏用到了子查詢且返回相對少的行時,該提示可以儘可能早對子查詢進行評估從而改善性能,不適用於合併連接或帶遠程表的連接.
例如:select/*+PUSH_SUBQ*/emp.empno,emp.ename,itemnofromemp,orderswhereemp.empno=orders.empnoandemp.deptno=(selectdeptnofromdeptwhereloc='XXX');

23./*+INDEX_SS(TABLEINDEX1,INDEX2)*/
指示對特定表的索引使用跳躍掃描,即當組合索引的第一列不在where子句中時,讓其使用該索引.


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