oracle 部分常用hint

        RBO: Rule-Based Optimization 基於規則的優化器。它只認規則,對數據不敏感。畢竟規則是死的,數據是變化的,這樣生成的執行計劃往往是不可靠的。索引的優先級比全表掃描高,則由索引則走索引。
        CBO: Cost-Based Optimization 基於代價的優化器。CBO是根據SQL語句生成一組可能被使用的執行計劃和cost,從中選用代價COST最低的執行方案,作爲實際運行方案。它對數據敏感,執行計劃會根據數據量做調整它依賴數據庫對象的統計信息,統計信息的準確與否會影響CBO做出最優的選擇。如果對一次執行SQL時發現涉及對象(表、索引等)沒有被分析、統計過,那麼ORACLE會採用一種叫做動態採樣的技術,動態的收集表和索引上的一些數據信息。
		CBO包括組件:查詢轉化器、代價評估器、計劃生成器
從ORACLE 10g開始不支持RBO
oracle優化器:(CBO模式:)first_rows_n , all_rows , choose , (RBO模式:)rule
	CHOOSE:默認值。有一個或多個有統計信息,那麼使用CBO。如果所有表都沒有統計信息,Oracle就會採用RBO。
	ALL_ROWS:不管是不是有統計信息,全部採用CBO。
	FIRST_ROWS_n:不管是不是有統計信息,全部採用基於成本的優化方法CBO,並以最快的速度,返回前N行記錄。後面的n值可以爲1,100,1000
	FIRST_ROWS:使用成本和試探法相結合的方法,查找一種可以最快返回前面少數行的方法;這個參數主要用於向後兼容。
	RULE:不管是不是統計信息,全部採用RBO。
系統級別:alter system set optimizer_mode=rule scope=both;
會話級別:alter session set optimizer_mode=first_row_100;
語句級別:使用提示hints來實現 select /*+ rule*/ * from dba_objects where rownum<=10;
optimizer_mode=rule scope=both;
會話級別:alter session set optimizer_mode=first_row_100;
語句級別:使用提示hints來實現 select /*+ rule*/ * from dba_objects where rownum<=10;
//並行update
alter session enable parallel dml;	//臨時更改會話爲並行,下面的並行更新才生效
update /*+ parallel(x,100)*/ all01 x set timee=to_date(riqi||' '||shijian,'yyyy-mm-dd hh24:mi:ss')
commit;
語法:/*+parallel(table_short_name,cash_number)*/ 可以加到insert、delete、update、select的後面來使用,cash_number爲cpu個數*2
並行查詢運行時,很容易會使機器運行在高負荷下,令系統對其它事務的處理時間大大加長.並行查詢一般適合在非業務高峯值人工執行,並不適合在程序中指定運行並行查詢.。當有多個表時,請指定某一個表,否則會默認所有表
select /*+ parallel(A 8) parallel(B 8) parallel(C 8) parallel(D 8) */
from A,B,C,D  where .....

查看執行計劃:
explain plan for select * from table
select * from table(dbms_xplan.display); //查看
----
Append一般跟nologging使用
insert /*+ Append parallel(tablename,number) */ into ods_list_t nologging  as  select * from ods_list;
insert /*+ append, parallel */ into ods_list_t nologging   select * from ods_list;
insert /*+ append, parallel */ into ods_list_t(a,b) nologging  select a,b from ods_list; //這樣不行:整個表可以插入,但要某一個字段則不能加入nologging
   可以這樣:insert /*+ append, parallel */ into ods_list_t  nologging(a,b)  select a,b from ods_list;
使用批量拷貝方法
	set arraysize 20
	set copycommit 5000
	copy from username/password@oracle_name append table_name1 
	using select * from table_name2;

非歸檔與歸檔方式,只用NOLOGGING是不起效果的。需增加下面的修改  ***
	sys@ORCL>alter table tb_a nologging;     --不記錄日誌模式
	sys@ORCL>alter table tb_a logging;       --採用日誌記錄模式
表是否是nologging模式,還需要查user_tables.logging字段才行。***
***
	sys@ORCL>alter table tb_a nologging;     --不記錄日誌模式
	sys@ORCL>alter table tb_a logging;       --採用日誌記錄模式
表是否是nologging模式,還需要查user_tables.logging字段才行。***

 
部分常用hint。
  1.全表掃描hint full(table_name)
  相對而言,全表掃描hint使用場合較少,但是要知道,全表掃描並不一定比索引效率低,特別是查詢表中80%以上的數據庫,全表掃描的效率要高於索引掃描。
  2.索引hint index(table_name index_name)
  這兩種hint一個是強制使用索引,另一個是強制執行計劃不要走索引,什麼用呢?常用於SQL調優過程中對比索引和非索引掃描。SELECT /*+INDEX(BSEMPMS SEX_INDEX) USE SEX_INDEX BECAUSE THERE ARE FEWMALE BSEMPMS */ FROM BSEMPMS WHERE SEX='M';
3.索引快速掃描hint index_ffs(table_name index_name)
  這種索引稱之爲索引快速掃描,常用於統計索引列鍵值的個數,如count(object_id),跟全表掃描很像,但效率要比全表掃描要高很多,也就是執行計劃中看到的FAST FULL SCN。
4.索引跳躍掃描hint index_ss(table_name index_name)
  該hint在執行計劃中就是傳說中的 INDEX SKIP SCAN 這個對新手而言不太好理解,舉個例子索引有兩個列(A,B)類型組合索引,但是查詢中where條件只有B沒有A select * from where b=1,此時ORACLE優化器走的索引就是所謂的索引跳躍掃描,只在CBO下適用,在RBO不適用。
      5.表關聯hint  user_nl(table_name1 table_name2)
  此hint是表之間關聯效率最高的一種,通常用於一大一小兩表之間進行關聯查詢,小表作驅動表進行全表掃描,大表上要求有索引,走索引掃描,代價最低。
  6.表關聯hint use_hash(table_name1 table_name2)
  如果兩個表一大一小,但是大表沒有索引就會選擇HASH,如果兩個結果集比較小還可以承受,但是如果兩個較大的表HASH的話,會直接將數據庫HANG住,最好避免這種算法SELECT /*+USE_HASH(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
      7.表關聯hint  user_merge(table_name1 table_name2)
  兩個表進行關聯,分別對全個表進行全表掃描後排序然後進行合併,排序既消耗內存又消耗CPU,總之代價比較大,常通過在兩個表上創建索引避免此類連接的發生。因此對比後發現,只有nested_loop方式進行關聯是最優的。SELECT /*+USE_MERGE(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
  8.表順序hint leading(table_name1 table_name2)
  在RBO模式下,我們常常通過考慮from 後面表的先後順序來進行SQL優化,但是此方法對RBO模式不再適用,CBO模式下按照順序選擇驅動表
9.數據加載hint append()
  直接路徑加載,對於大表操作極爲有用,原理是什麼呢?打個比方,好比兩個超市理貨員,一人一箱貨需要上架到貨架上,一個人去找貨架中空閒位置去放,可能需要找N個空閒位,另一個人找一個空的貨架直接放上去,那個效果最高?當然是第二個,此hint的作用就是讓ORACLE找一個大空親塊直接存放新數據,而不是擠空閒位置去放新數據,如果此hint同時加上nologing聯合使用效果更高,常用於數據遷移項目中。insert /*+append*/ into test1 select * from test4 ;
  10.dblink處理端hint driving_site(table_name)
  此hint常用於通過dblink連接處理數據的業務,它的作用是將本地表推送到遠端數據庫進行關聯然後將結果返回,常用於本地表較小,遠端表較大的情況,效果很是不錯。
  11.數據返回模式hint first_rows
  該hint是影響數據返回模式hint,只要有數據立刻返回數據,添加後ORACLE將邊處理邊返回,數據倉庫中用的比較多,但是在OLTP系統中也常見,上次系統優化就因爲一兄弟在添加hint 時,添加後發現執行計劃沒變,於是將原有的hint first_rows 然後添加hint driving_site(),執行計劃是變了,變化是因去去掉first_rows引起的,並且通過dblink遠端數據庫執行時查詢全變成的全表掃描,導致兩個業務大表hash,業務高峯直接將數據庫宕機,因此該hint添加或刪除一定要看遠端執行計劃有無發生變化,否則後果不開設想(切記)。SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';
  特別需要注意的是,使用hint時切記查看錶名是否使用了別名,如果使用了別名,記得要在hint中也要使用別名,否則hint是沒有作用的(切記)
  1.全表掃描hint full(table_name)
  相對而言,全表掃描hint使用場合較少,但是要知道,全表掃描並不一定比索引效率低,特別是查詢表中80%以上的數據庫,全表掃描的效率要高於索引掃描。
  2.索引hint index(table_name index_name)
  這兩種hint一個是強制使用索引,另一個是強制執行計劃不要走索引,什麼用呢?常用於SQL調優過程中對比索引和非索引掃描。SELECT /*+INDEX(BSEMPMS SEX_INDEX) USE SEX_INDEX BECAUSE THERE ARE FEWMALE BSEMPMS */ FROM BSEMPMS WHERE SEX='M';
3.索引快速掃描hint index_ffs(table_name index_name)
  這種索引稱之爲索引快速掃描,常用於統計索引列鍵值的個數,如count(object_id),跟全表掃描很像,但效率要比全表掃描要高很多,也就是執行計劃中看到的FAST FULL SCN。
4.索引跳躍掃描hint index_ss(table_name index_name)
  該hint在執行計劃中就是傳說中的 INDEX SKIP SCAN 這個對新手而言不太好理解,舉個例子索引有兩個列(A,B)類型組合索引,但是查詢中where條件只有B沒有A select * from where b=1,此時ORACLE優化器走的索引就是所謂的索引跳躍掃描,只在CBO下適用,在RBO不適用。
      5.表關聯hint  user_nl(table_name1 table_name2)
  此hint是表之間關聯效率最高的一種,通常用於一大一小兩表之間進行關聯查詢,小表作驅動表進行全表掃描,大表上要求有索引,走索引掃描,代價最低。
  6.表關聯hint use_hash(table_name1 table_name2)
  如果兩個表一大一小,但是大表沒有索引就會選擇HASH,如果兩個結果集比較小還可以承受,但是如果兩個較大的表HASH的話,會直接將數據庫HANG住,最好避免這種算法SELECT /*+USE_HASH(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
      7.表關聯hint  user_merge(table_name1 table_name2)
  兩個表進行關聯,分別對全個表進行全表掃描後排序然後進行合併,排序既消耗內存又消耗CPU,總之代價比較大,常通過在兩個表上創建索引避免此類連接的發生。因此對比後發現,只有nested_loop方式進行關聯是最優的。SELECT /*+USE_MERGE(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
  8.表順序hint leading(table_name1 table_name2)
  在RBO模式下,我們常常通過考慮from 後面表的先後順序來進行SQL優化,但是此方法對RBO模式不再適用,CBO模式下按照順序選擇驅動表
9.數據加載hint append()
  直接路徑加載,對於大表操作極爲有用,原理是什麼呢?打個比方,好比兩個超市理貨員,一人一箱貨需要上架到貨架上,一個人去找貨架中空閒位置去放,可能需要找N個空閒位,另一個人找一個空的貨架直接放上去,那個效果最高?當然是第二個,此hint的作用就是讓ORACLE找一個大空親塊直接存放新數據,而不是擠空閒位置去放新數據,如果此hint同時加上nologing聯合使用效果更高,常用於數據遷移項目中。insert /*+append*/ into test1 select * from test4 ;
  10.dblink處理端hint driving_site(table_name)
  此hint常用於通過dblink連接處理數據的業務,它的作用是將本地表推送到遠端數據庫進行關聯然後將結果返回,常用於本地表較小,遠端表較大的情況,效果很是不錯。
  11.數據返回模式hint first_rows
  該hint是影響數據返回模式hint,只要有數據立刻返回數據,添加後ORACLE將邊處理邊返回,數據倉庫中用的比較多,但是在OLTP系統中也常見,上次系統優化就因爲一兄弟在添加hint 時,添加後發現執行計劃沒變,於是將原有的hint first_rows 然後添加hint driving_site(),執行計劃是變了,變化是因去去掉first_rows引起的,並且通過dblink遠端數據庫執行時查詢全變成的全表掃描,導致兩個業務大表hash,業務高峯直接將數據庫宕機,因此該hint添加或刪除一定要看遠端執行計劃有無發生變化,否則後果不開設想(切記)。SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';
  特別需要注意的是,使用hint時切記查看錶名是否使用了別名,如果使用了別名,記得要在hint中也要使用別名,否則hint是沒有作用的(切記)
<span style="color:#ff6666">===================</span>

1. /*+ALL_ROWS*/
表明對語句塊選擇基於開銷的優化方法,並獲得最佳吞吐量,使資源消耗最小化.
例如:
SELECT /*+ALL+_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';

3. /*+CHOOSE*/
表明如果數據字典中有訪問表的統計信息,將基於開銷的優化方法,並獲得最佳的吞吐量;
表明如果數據字典中沒有訪問表的統計信息,將基於規則開銷的優化方法;
例如:

SELECT /*+CHOOSE*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';

4. /*+RULE*/
表明對語句塊選擇基於規則的優化方法.
例如:

SELECT /*+ RULE */ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';

6. /*+ROWID(TABLE)*/
提示明確表明對指定表根據ROWID進行訪問.
例如:
SELECT /*+ROWID(BSEMPMS)*/ * FROM BSEMPMS WHERE ROWID>='AAAAAAAAAAAAAA'

AND EMP_NO='SCOTT';

7. /*+CLUSTER(TABLE)*/
提示明確表明對指定表選擇簇掃描的訪問方法,它只對簇對象有效.
例如:
SELECT /*+CLUSTER */ BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMS

WHERE DPT_NO='TEC304' AND BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;

9. /*+INDEX_ASC(TABLE INDEX_NAME)*/
表明對錶選擇索引升序的掃描方法.
例如:

SELECT /*+INDEX_ASC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT';

10. /*+INDEX_COMBINE*/
爲指定表選擇位圖訪問路經,如果INDEX_COMBINE中沒有提供作爲參數的索引,將選擇出位圖索引的布爾組合方式.
例如:
SELECT /*+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI)*/ * FROM BSEMPMS
WHERE SAL<5000000 AND HIREDATE<SYSDATE;
11. /*+INDEX_JOIN(TABLE INDEX_NAME)*/
提示明確命令優化器使用索引作爲訪問路徑.
例如:
SELECT /*+INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)*/ SAL,HIREDATE
FROM BSEMPMS WHERE SAL<60000;
12. /*+INDEX_DESC(TABLE INDEX_NAME)*/
表明對錶選擇索引降序的掃描方法.
例如:

SELECT /*+INDEX_DESC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT';

13. /*+INDEX_FFS(TABLE INDEX_NAME)*/
對指定的表執行快速全索引掃描,而不是全表掃描的辦法.
例如:

SELECT /*+INDEX_FFS(BSEMPMS IN_EMPNAM)*/ * FROM BSEMPMS WHERE DPT_NO='TEC305';

14. /*+ADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,...*/
提示明確進行執行規劃的選擇,將幾個單列索引的掃描合起來.
例如:

SELECT /*+INDEX_FFS(BSEMPMS IN_DPTNO,IN_EMPNO,IN_SEX)*/ * FROM BSEMPMS WHERE EMP_NO='SCOTT' AND DPT_NO='TDC306';

15. /*+USE_CONCAT*/
對查詢中的WHERE後面的OR條件進行轉換爲UNION ALL的組合查詢.
例如:
SELECT /*+USE_CONCAT*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M';
16. /*+NO_EXPAND*/
對於WHERE後面的OR 或者IN-LIST的查詢語句,NO_EXPAND將阻止其基於優化器對其進行擴展.
例如:

SELECT /*+NO_EXPAND*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M';

17. /*+NOWRITE*/
禁止對查詢塊的查詢重寫操作.
18. /*+REWRITE*/
可以將視圖作爲參數.
19. /*+MERGE(TABLE)*/
能夠對視圖的各個查詢進行相應的合併.
例如:
SELECT /*+MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELET DPT_NO
,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO

AND A.SAL>V.AVG_SAL;

20. /*+NO_MERGE(TABLE)*/
對於有可合併的視圖不再合併.
例如:
SELECT /*+NO_MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELECT DPT_NO,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO AND A.SAL>V.AVG_SAL;
21. /*+ORDERED*/
根據表出現在FROM中的順序,ORDERED使ORACLE依此順序對其連接.
例如:

SELECT /*+ORDERED*/ A.COL1,B.COL2,C.COL3 FROM TABLE1 A,TABLE2 B,TABLE3 C WHERE A.COL1=B.COL1 AND B.COL1=C.COL1;

27. /*+CACHE(TABLE)*/
當進行全表掃描時,CACHE提示能夠將表的檢索塊放置在緩衝區緩存中最近最少列表LRU的最近使用端
例如:
SELECT /*+FULL(BSEMPMS) CAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;
28. /*+NOCACHE(TABLE)*/
當進行全表掃描時,CACHE提示能夠將表的檢索塊放置在緩衝區緩存中最近最少列表LRU的最近使用端
例如:

SELECT /*+FULL(BSEMPMS) NOCAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;

30. /*+NOAPPEND*/
通過在插入語句生存期內停止並行模式來啓動常規插入.
insert /*+noappend*/ into test1 select * from test4 ;

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