優化器提示
提示(Hint)概念
一般在優化時,無論採用基於規則的或是基於代價的方法,由Oracle 系統的優化器來決定語
句的執行路徑。這樣的選擇的路徑不要見得是最好的。所以,Oracle 提供了一種方法叫提示的
方法。它可以讓程式設計人員按照自己的要求來選擇執行路徑,即提示優化器該按照什麼樣的執
行規則來執行當前的語句。這樣可以在效能上比起Oracle 優化自主決定要好些。
通常情況下,程式設計人員可以利用提示來進行優化決策。通過運用提示可以對下面內容進行指
定:
SQL 語句的優化方法;
對於某條SQL 語句,基於開銷優化程式的目標;
SQL 語句訪問的訪問路徑;
連線語句的連線次序;
連線語句中的連線操作
提示的指定
如果希望優化器按照程式設計人員的要求執行,則要在語句中給出提示。提示的有效範圍有
限制,即有提示的語句塊才能按照提示要求執行。下面語句可以指定提示:
簡單的SELECT ,UPDATE ,DELETE 語句;
複合的主語句或子查詢語句;
組成查詢(UNION)的一部分。
提示的指定有原來的註釋語句在加“+”構成。語法如下:
[ SELECT | DELETE|UPDATE ] /*+ [hint | text ] */
或
[ SELECT | DELETE|UPDATE ] --+ [hint | text ]
注意在“/*”後不要空就直接加“+”,同樣 “--+”也是連著寫。
警告:如果該提示語句書寫不正確,則 Oracle 就忽略掉該語句。
指定完整的提示:
對於複雜的語句,要用/*+ */來指定,它可以指定多個提示語句。且可以換行。
SELECT /*+ ORDERED INDEX (b, jl_br_balances_n1) USE_NL (j b)
USE_NL (glcc glf) USE_MERGE (gp gsb) */
b.application_id ,
b.set_of_books_id ,
b.personnel_id,
p.vendor_id Personnel,
p.segment1 PersonnelNumber,
p.vendor_name Name
FROM jl_br_journals j,
jl_br_balances b,
gl_code_combinations glcc,
fnd_flex_values_vl glf,
gl_periods gp,
gl_sets_of_books gsb,
po_vendors p
WHERE . . . . . . . . . . . .
提示的指定
使用提示,使用者可以在基於開銷的優化方法和基於規則的優化方法之間選擇,由此可以
對要求“最佳吞吐量”與“最佳響應時間”優化目標進行選擇。優化方法如下:
ALL_ROWS
FIRST_ROWS
CHOOSE
RULE
如果某條語句已經指定了優化方法和優化目標後,則Oracle 的優化器就按照指定的優化方法
和目標進行執行。並且不考慮:
1) 是否存在統計資訊;
2) 初始化引數OPTIMIZER_MODE 的取值;
3) ALTER SESSION 語句中OPTIMIZER_MODE 引數值。
ALL_ROWS
ALL_ROWS 表示對語句塊選擇基於開銷的優化方法,並且獲得最佳的吞吐量(資源消耗
總量最小)作為目標進行優化。語法如下:
/*+ ALL_ROWS */
例子:在查詢EMP 表希望用基於開銷的優化方法,並獲得最佳吞吐量,則使用下面語句:
SELECT /*+ ALL_ROWS */empno,ename,sal,job
FROM emp WHERE empno=7566;
FIRST_ROWS
FIRST_ROWS 表示對語句塊選擇基於開銷的優化方法,並且獲得最佳的響應(返回首行
的資源最小化)作為目標進行優化。
使用FIRST_ROWS 優化方法,優化器可能要進行下面工作:
如果能利用索引掃描,則不進行全表掃描;
當關聯表是巢狀迴圈的內部表且能用索引掃描,則優化器先優化巢狀迴圈聯結。
如果通過order by 使得索引掃描可用,則優化器選擇索引掃描以避免排序操作。
語法如下:
/*+ FIRST_ROWS */
例子:選擇基於開銷的優化方法,並希望獲得最佳的響應時間,則:
SELECT /*+ FIRST_ROWS */empno,ename,sal,job
FROM emp
WHERE empno=7566;
CHOOSE
選擇CHOOSE 表示告訴優化器要在基於開銷和基於規則之間進行選擇。優化器的確定要
建立在是否存在訪問表的統計資訊之上:
如果資料字典中存在該表的統計資料,則選擇基於開銷,並以最佳吞吐量作為目標。
如果資料字典中不存在該表的統計資料,則選擇基於規則。
語法為:
/*+ CHOOSE */
例子:
SELECT /*+ CHOOSE */ empno,sal,job FROM emp WHERE empno=7566;
RULE
表示要求優化器對語句塊選擇基於規則的優化方法。語法如下:
/*+ RULE */
例子:
SELECT --+ RULE empno,ename,sal,job
FROM emp WHERE empno=7655;
或
SELECT /*+ RULE */ empno,ename,sal,job
FROM emp WHERE empno=7655;
訪問方法共有:
FULL
ROWID
CLUSTER
HASH
INDEX
INDEX_ASC
INDEX_COMBINE
INDEX_JOIN
INDEX_DESC
INDEX_FFS
NO_INDEX
AND_EQUAL
USE_CONCAT
NO_EXPAND
REWRITE
NOREWRITE
如果在語句中指定了上面的提示,並且語句所涉及的索引或簇是可用時,優化器就使用所指
定的訪問路徑。否則,優化器就忽略提示的要求。
FULL
FULL 提示表示對錶選擇全表掃描的訪問方法。語法如下:
/*+ FULL ( [table_name]| [table_aliase] ) */
例:
SELECT /*+ FULL(A) don’t use the index on accno */ accno,bal
FROM accounts a
WHERE accno=7789;
雖然這裡使用了帶索引的條件句,優化器也得選擇全表掃描。
ROWID
ROWID 表示對指定表選擇根據rowid 進行表掃描,語法如下:
/*+ ROWID( table_name ) */
例:
SELECT /*+ROWID(emp)*/ * FROM emp
WHERE rowid>’AAAATKAABAAAFNTAAA’ AND empno=155;
CLUSTER
CLUSTER 表示對指定表選擇簇掃描的訪問方法。它僅對CLUSTER 物件有效。語法如
下:
/*+CLUSTER(table_name) */
例:
SELECT --+CLUSTER emp.ename, deptno
FROM emp,dept
WHERE deptno=10 AND emp.deptno=dept.deptno;
HASH
HASH 表示對指定的表選擇HASH 掃描訪問方法,它只對CLUSTER 中的表有效。語法
如下:
/*+HASH(table_name)*/
INDEX
INDEX 表示對指定表選擇索引掃描的訪問方法。使用者可以對域、B*樹和點陣圖索引應用本
提示。對於建立了點陣圖的索引,建議用INDEX_COMBINE 更為合適。語法如下:
/*+INDEX(table_name [index]) */
例:
SELECT /*+INDEX(patients sex_index)use sex_index because there are few male patients*/
Name,height,weight FROM patients WHERE sex=’m’;
INDEX_ASC
INDEX_ASC 表示對指定的表選擇索引的訪問方法,並按照升序進行掃描。語法如下:
/*+INDEX_ASC(table_name [index])*/
INDEX_COMBINE
INDEX_COMBINE 表示對指定的表選擇點陣圖訪問路徑。
如果沒有提供可參考的索引,則優化器以最低開銷為目標,選擇點陣圖索引的布林組合
方式;
如果有可參考的索引,則優化器就使用該點陣圖的某寫布林組合。
語法如下:
/*+INDEX_COMBINE(table_name[index])*/
例:
SELECT /*+INDEX_COMBINE(emp sal_bmi hiredate_bmi)*/*
FROM emp
WHERE sal<5000 AND hiredate ,’01-JAN-1990’;
INDEX_JOIN
INDEX_JOIN 表示使用索引連線作為訪問路徑。語法如下:
/*+INDEX_JOIN(table_name[index])*/
例:
SELECT /*+INDEX_JOIN(emp sal_bmi hiredate_bmi)*/sal,hirdate
FROM emp
WHERE sal<5000 ;
INDEX_DESC
INDEX_DESC 表示對指定表選擇索引訪問方法。如果使用索引區域掃描,則按照降序進
行掃描。語法如下:
/*+INDEX_DESC(table_name[index])*/
INDEX_FFS
INDEX_DESC 表示對指定表選擇快速索引訪問方法(不是全表掃描)。語法如下:
/*+INDEX_FFS(table_name[index])*/
例:
SELECT /*+INDEX_FFS(emp emp_empnp)*/ empno
FROM emp
WHERE empno>200;
NO_INDEX
NO_INDEX 表示對指定表禁止選擇索引訪問方法。語法如下:
/*+NO_INDEX(table_name[index])*/
例:
SELECT /*+NO_INDEX(emp emp_empnp)*/ empno
FROM emp
WHERE empno>200;
AND_EQUAL
AND-EQUAL 表示要進行執行規則的選擇。使幾個列的索引的掃描合併起來。語法如
下:
/*+AND_EQUAL(table_name[index] [inex]…)*/
USE_CONCAT
USE_CONCAT 提示強制對查詢語句中的WHERE 從句的OR 條件進行轉換,轉化成由
UNION_ALL 集合操作符連線的組合查詢。一般來說,如果採用連線查詢比不用連線查詢低,
則轉換為用連線查詢。
/*+USE_COMCAT*/
例:
SELECT /*USE_CONCAT*/* FROM emp
WHERE empno>50 OR sal<50000;
NO_EXPAND
NO_EXPAND 對於具有OR 或IN 查詢語句,它將阻止基於開銷的優化器對其進行OR 擴
展。語法如下:
/*+NO_EXPAND*/
例:
SELECT /*+NO_EXPAND*/*
FROM emp
WHERE empno=50 OR empno=100;
REWRITE
REWRITE 表示可以將檢視列表作為引數來看,如果使用者使用REWRITE,並且該列表包
含有符合條件的實體化檢視,則Oracle 優化器將利用該檢視而不用基於開銷的方法。而對於
列表以外的檢視將不被考慮。如果在REWRITE 中沒有給出檢視列表,則Oracle 將搜尋符合
條件的實體化檢視。並且利用該檢視。語法如下:
/*+REWRITE(view,[view]…)*/
NOWRITE
NOWRITE 表示禁止對查詢塊的查詢重寫操作, 從而避免引數
QUERY_REWRITE_ENABLE 的設定。語法如下:
/*+NOWRITE*/
關於連線次序的提示
ORDERED
根據出現在FROM 中順序,ORDERED 提示將使得Oracle 依此次序對其進行連線。語法
如下:
/*+ORDERED*/
例:
SELECT /*+ORDERED*/tab1.col1,tabl2.col2,tab3.col3
FROM tab1,tab2,tab3
WHERE tab1.col1=tab2.col1 AND tab2.col1=tab3.col1;
STAR
強行讓優化器使用星型查詢規劃。星型規劃擁有查詢中最大的一個表,該表位於連線次
序的最後,並與巢狀式迴圈連線的級聯索引連線。如果滿足下面3個條件:
1)至少存在3個表;
2)最大表的級聯索引至少存在3列;
3)不存在衝突的訪問或連線訪問提示。
/*+ STAR */
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26015009/viewspace-746386/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [20181220]使用提示OR_EXPAND優化.txt優化
- [20190524]使用use_concat or_expand提示優化.txt優化
- [原始碼解析] PyTorch分散式優化器(2)----資料並行優化器原始碼PyTorch分散式優化並行
- 前端效能優化 —— 移動端瀏覽器優化策略前端優化瀏覽器
- TiDB 查詢優化及調優系列(一)TiDB 優化器簡介TiDB優化
- pytorch optim 優化器核心分析PyTorch優化
- 優化器的發展程式優化
- CSS 選擇器效能優化CSS優化
- SQL優化器探討(zt)SQL優化
- C++編譯器優化C++編譯優化
- MySQL查詢優化之優化器工作流程以及優化的執行計劃生成MySql優化
- Mysql優化系列之——優化器對子查詢的處理MySql優化
- 早餐|第十七期 · 模型優化器對模型做了哪些優化模型優化
- 資料庫應用優化(二)伺服器和配置優化資料庫優化伺服器
- TiDB與MySQL優化器對照TiDBMySql優化
- 深入瞭解 TiDB SQL 優化器TiDBSQL優化
- 編譯器優化:方法內聯編譯優化
- 優化器:SGD > Momentum > AdaGrad > RMSProp > Adam優化
- PostgreSQL 優化器程式碼概覽SQL優化
- TensorFlow筆記(5)——優化手寫數字識別模型之優化器筆記優化模型
- win10系統優化驅動器怎麼用_win10如何優化驅動器Win10優化
- HttpRunner 的結果校驗器優化HTTP優化
- 淺談Tomcat伺服器優化方法Tomcat伺服器優化
- LightDB-像Oracle一樣使用最佳化器提示(十)Oracle
- 前端效能優化(JS/CSS優化,SEO優化)前端優化JSCSS
- 如何調優 Oracle SQL系列文章:查詢優化器介紹OracleSQL優化
- MySQl 配置InnoDB持久化的優化器統計資訊MySql持久化優化
- 程式分析與優化 - 8 暫存器分配優化
- Linux 下如何繞過編譯器優化Linux編譯優化
- IIS網站伺服器效能優化攻略網站伺服器優化
- 前端效能優化(一)——瀏覽器工作原理前端優化瀏覽器
- 【C/C++】 C++暫存器優化C++優化
- 線上Linux伺服器優化經驗Linux伺服器優化
- 前端效能優化 之 瀏覽器快取前端優化瀏覽器快取
- win10優化驅動器有什麼用_win10如何啟用自動優化驅動器Win10優化
- 啥是伺服器虛擬化,虛擬化的優勢伺服器
- 阿里雲 RTC QoS 螢幕共享弱網優化之若干編碼器相關優化阿里優化
- 資料庫優化 - SQL優化資料庫優化SQL
- Android 效能優化 ---- 啟動優化Android優化