久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

怎么正確使用Oracle Hint

146次閱讀
沒有評論

共計 8346 個字符,預計需要花費 21 分鐘才能閱讀完成。

本篇內容主要講解“怎么正確使用 Oracle Hint”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓丸趣 TV 小編來帶大家學習“怎么正確使用 Oracle Hint”吧!

一、提示(Hint)概述 1、為什么引入 Hint?

Hint 是 Oracle 數據庫中很有特色的一個功能,是很多 DBA 優化中經常采用的一個手段。那為什么 Oracle 會考慮引入優化器呢?基于代價的優化器是很聰明的,在絕大多數情況下它會選擇正確的優化器,減輕 DBA 的負擔。

但有時它也聰明反被聰明誤,選擇了很差的執行計劃,使某個語句的執行變得奇慢無比。此時就需要 DBA 進行人為的干預,告訴優化器使用指定的存取路徑或連接類型生成執行計劃,從而使語句高效地運行。Hint 就是 Oracle 提供的一種機制,用來告訴優化器按照告訴它的方式生成執行計劃。

2、不要過分依賴 Hint

當遇到 SQL 執行計劃不好的情況,應優先考慮統計信息等問題,而不是直接加 Hint 了事。如果統計信息無誤,應該考慮物理結構是否合理,即沒有合適的索引。只有在最后仍然不能 SQL 按優化的執行計劃執行時,才考慮 Hint。

畢竟使用 Hint,需要應用系統修改代碼,Hint 只能解決一條 SQL 的問題,并且由于數據分布的變化或其他原因 (如索引更名) 等,會導致 SQL 再次出現性能問題。

3、Hint 的弊端

Hint 是比較 暴力 的一種解決方式,不是很優雅。需要開發人員手工修改代碼。

Hint 不會去適應新的變化。比如數據結構、數據規模發生了重大變化,但使用 Hint 的語句是感知變化并產生更優的執行計劃。

Hint 隨著數據庫版本的變化,可能會有一些差異、甚至廢棄的情況。此時,語句本身是無感知的,必須人工測試并修正。

4、Hint 與注釋關系

提示是 Oracle 為了不破壞和其他數據庫引擎之間對 SQL 語句的兼容性而提供的一種擴展功能。Oracle 決定把提示作為一種特殊的注釋來添加。它的特殊性表現在提示必須緊跟著 DELETE、INSERT、UPDATE 或 MERGE 關鍵字。

換句話說,提示不能像普通注釋那樣在 SQL 語句中隨處添加。且在注釋分隔符之后的第一個字符必須是加號。在后面的用法部分,會詳細說明。

5、Hint 功能

Hint 提供的功能非常豐富,可以很靈活地調整語句的執行過程。通過 Hint,我們可以調整:

優化器類型

優化器優化目標

數據讀取方式(訪問路徑)

查詢轉換類型

表間關聯的順序

表間關聯的類型

并行特性

其他特性

二、Hint 用法 1、語法

1)關鍵字說明

DELETE、INSERT、SELECT 和 UPDATE 是標識一個語句塊開始的關鍵字,包含提示的注釋只能出現在這些關鍵字的后面,否則提示無效。

+ 號表示該注釋是一個提示,該加號必須立即跟在 /* 的后面,中間不能有空格。

hint 是下面介紹的具體提示之一,如果包含多個提示,則每個提示之間需要用一個或多個空格隔開。

text 是其它說明 hint 的注釋性文本

2)提示中的錯誤

提示中的語法錯誤不會報錯,如果解析器不能解析它,就會把它看做一個普通注釋處理。這也是容易造成困惑的一點,使用的 Hint 到底是否起效?可以采用一些手段,檢查提示的有效性。需要注意的是,那些語法正確但引用對象錯誤的提示是不會被報告的。

explain plan + dbms_xplan

使用 dbms_xplan 輸出中的 note 選項。

10132 事件

在 10g 中,這個事件產生的輸出文檔的末尾有一部分內容專門講提示。通過它可以檢查兩個方面: 一是每個用到的提示都會被列出來。如果漏掉了哪個,就說明這個提示沒有被識別;二是檢查是否有一些信息指明了出現提示錯誤(如果出錯,err 值將大于 0)。

3)提示中的對象

SELECT /*+ INDEX(table_name index_name) */ …

table_name 是必須要寫的,且如果在查詢中使用了表的別名,在 hint 也要用表的別名來代替表名。

index_name 可以不必寫,Oracle 會根據統計值選一個索引。

如果索引名或表名寫錯了,那這個 hint 就會被忽略。

如果指定對象是視圖,需要按此方法指定。/*+hint view.table …*/,其中 table 是 view 中的表。

一個很常見的錯誤時,在使用提示的時候最易犯的錯誤是與表的別名有關。正確的規則是,當在提示中使用表時,只要表有別名就應該使用別名而不是表名。

2、提示的作用域

查詢塊

初始化參數提示對整個 SQL 語句起作用,其他的提示僅僅對查詢塊起作用。僅僅對單個查詢塊起作用的提示,必須在它控制的查詢塊內指定。

例外 – 全局提示

可以使用點號引用包含在其他查詢塊 (假設這些塊已命名) 中的對象。全局提示的語法可以支持兩層以上的引用,對象間必須用點號分隔。

命名查詢塊

既然 where 子句中的子查詢是沒有命名的,它們的對象就不能被全局提示引用。為了解決這個問題,10g 中使用了另一種方法來解決 - 命名查詢塊。查詢優化器可以給每個查詢生成一個查詢塊名,而且還可以使用提示 qb_name 手工為每個查詢塊命名。大多數提示都可以通過參數來指定在那個查詢塊中有效。

* 在提示中通過 @來引用一個查詢塊。

3、提示數據字典

Oracle 在 11g 的版本中提供了一個數據字典—V$SQL_HINT。通過這個數據字典可以看到提示的出現版本、概要數據版本、SQL 特性以及相反提示等。

INVERSE

這個 hint 相反操作的 hint。

VERSION

代表著這個 hint 正式公布引入的版本。

三、Hint 分類 1、和優化器相關的

當對優化器為某個語句所制定的基本執行計劃不滿意時,最好的辦法就是通過提示來轉換優化器的模式,并觀察其轉換后的結果,看是否已經達到期望程度。如果只通過轉換優化器的模式就可以獲得非常好的執行計劃,則就沒有必要額外使用更為復雜的提示了。

OPT_PARAM

這個提示的作用就是使我們在某條語句中指定某個系統參數值。

ALL_ROWS

為實現查詢語句整體最優化而引導優化器制定最少成本的執行計劃。這個提示會使優化器選擇一條可最快檢索所有查詢行的路徑,而代價就是在檢索一行數據時,速度很慢。

FIRST_ROWS 

為獲得最佳響應時間而引導優化器制定最少成本的執行計劃。這個提示會使優化器選擇可最快檢索出查詢的第一行 (或指定行) 數據的路徑,而代價就是檢索很多行時速度就會很慢。利用 FIRST_ROWS 來優化的行數,默認值為 1,這個值介于 10 到 1000 之間,這個使用 FIRST_ROWS(n)的新方法是完全基于代價的方法。它對 n 很敏感,如果 n 值很小,CBO 就會生成包含嵌套循環以及索引查找的計劃;如果 n 很大,CBO 會生成由哈希連接和全表掃描組成的計劃(類似 ALL_ROWS)。

CHOOSE

依據 SQL 中所使用到的表的統計信息存在與否,來決定使用 RBO 還是 CBO。在 CHOOSE 模式下,如果能夠參考表的統計信息,則將按照 ALL_ROWS 方式執行。除非在查詢中的所有表都沒有經過分析,否則 choose 提示會對整個查詢使用基于代價的優化。如果在多表連接中有一個表經過分析過,那么就會對整個查詢進行基于代價的優化。

RULE 

使用基于規則的優化器來實現最優化執行,即引導優化器根據優先順序規則來決定查詢條件中所使用到的索引或運算符的執行順序來制定執行計劃。這個提示強制 oracle 優先使用預定義的一組規則,而不是對數據進行統計;同時該提示還會使這個語句避免使用其他提示,除了 DRIVING_SITE 和 ORDERED(不管是否進行基于規則的優化,這兩個提示都可使用)。

2、和訪問路徑相關的

FULL

告訴優化器通過全表掃描方式訪問數據。這個提示只對所指定的表進行全表掃描,而不是查詢中的所有表。FULL 提示可以改善性能。這主要是因為它改變了查詢中的驅動表,而不是因為全表掃描。在使用其他某些提示時,也必須使用 FULL 提示。只有訪問整個表時,才可利用 CACHE 提示將表進行緩存。并行組中的某些提示也必須使用全表掃描。 

CLUSTER

引導優化器通過掃描聚簇索引來從索引表中讀取數據。

HASH

引導優化器按照哈希掃描的方式從表中讀取數據。

INDEX

告訴優化器對指定表通過索引的方式訪問數據。當訪問數據會導致結果集不完整時,優化器將忽略這個 Hint。

NO_INDEX

告訴優化器對指定表不允許使用索引。這個提示會禁止優化器使用指定索引??梢栽趧h除不必要的索引之前在許多查詢中禁止索引。如果使用了 NO_INDEX,但是沒有指定任何索引,則會執行全表掃描。如果對某個索引同時使用了 NO_INDEX 和會之產生沖突的提示(如 INDEX),這時兩個提示都會被忽略掉。

INDEX_ASC

利用索引從表中讀取數據時,引導優化器對提示中所指定索引的索引列值按照升序使用范圍掃描。

INDEX_COMBINE

告訴優化器強制選擇位圖索引。這個提示會使優化器合并表上的多個位圖索引,而不是選擇其中最好的索引(這是 INDEX 提示的用途)。還可以使用 index_combine 指定單個索引(對于指定位圖索引,該提示優先于 INDEX 提示)。對于 B 樹索引,可以使用 AND_EQUAL 提示而不是這個提示。

INDEX_JOIN

索引關聯,當謂詞中引用的列上都有索引的時候,可以通過索引關聯的方式來訪問數據。這個提示可以將同一個表的各個不同索引進行合并,這樣就只需要訪問這些索引就可以了,節省了回表查詢的時間。但只能在基于代價的優化器中使用該提示。這個提示不僅允許只訪問表上的索引,這樣可以掃描更少的代碼塊,并且它比使用索引并通過 rowid 掃描整個表快 5 倍。

INDEX_DESC

利用索引從表中讀取數據時,引導優化器對提示中所指定索引的索引列值按照降序使用范圍掃描。

INDEX_FFS

告訴優化器以 INDEX FFS(index fast full scan)的方式訪問數據。INDEX_FFS 提示會執行一次索引的快速全局掃描。這個提示只訪問索引,而不是對應的表。只有查詢需要檢索的信息都在索引上時,才使用這個提示。特別在表有很多列時,使用該提示可以極大地改善性能。

INDEX_SS

強制使用 index skip scan 的方式訪問索引。當在一個聯合索引中,某些謂詞條件并不在聯合索引的第一列時(或者謂詞并不在聯合索引的第一列時),可以通過 index skip scan 來訪問索引獲得數據。當聯合索引第一列的唯一值很少時,使用這種方式比全表掃描的方式效率要高。

3、和查詢轉換相關的

USE_CONCAT

將含有多個 OR 或者 IN 運算符所連接起來的查詢語句分解為多個單一查詢語句,并為每個單一查詢語句選擇最優化查詢路徑,然后再將這些最優化查詢路徑結合在一起,以實現整體查詢語句的最優化目的。只有在驅動查詢條件中包含 OR 的時候,才可以使用該提示。

NO_EXPAND

引導優化器不要為使用 OR 運算符號 (或 IN 運算符) 的條件制定相互結合的執行計劃。正好和 USE_CONCAT 相反。

REWRITE

當表連接的對象是數據量比較大的表或者需要獲得使用統計函數處理過的結果時,為了提高執行速度可預先創建物化視圖。當用戶要求查詢某個查詢語句時,優化器會在從表中和從物化視圖中讀取數據的兩種方法中選擇一個更有效的方法來讀取數據。該執行方法稱之為查詢重寫。使用 REWRITE 提示引導優化器按照該方式執行。

MERGE

為了能以最優方式從視圖或者嵌套視圖中讀取數據,通過變換查詢語句來直接讀取視圖使用的基表數據,該過程被稱之為視圖合并。不同的情況其具體使用類型也有所不同。該提示主要在視圖未發生合并時被使用。尤其是對比較復雜的視圖或者嵌套視圖 (比如使用了 GROUP BY 或 DISTINC 的視圖) 使用該提示,有時會取得非常好的效果。

UNNEST

提示優化器將子查詢轉換為連接的方式。也就是引導優化器合并子查詢和主查詢并且將其向連接類型轉換。

NO_UNNEST

引導優化器讓子查詢能夠獨立地執行完畢之后再跟外圍的查詢做 FILTER。

PUSH_PRED

使用該提示可以將視圖或嵌套視圖以外的查詢條件推入到視圖之內。

NO_PUSH_PRED

使用該提示確保視圖或嵌套視圖以外的查詢條件不被推入到視圖內部。

PUSH_SUBQ

使用該提示引導優化器為不能合并的子查詢制定執行計劃。不能合并的子查詢被優先執行之后,該子查詢的執行結果將扮演縮減主查詢數據查詢范圍的提供者角色。通常在無法執行子查詢合并的情況下,子查詢扮演的都是檢驗者角色,所以子查詢一般被放在最后執行。在無法被合并的子查詢擁有較少的結果行,或者該子查詢可以縮減主查詢查詢范圍的情況下,可以使用該提示引導優化器最大程度地將該子查詢放在前面執行,以提高執行速度。但如果子查詢執行的是遠程表或者排序合并連接的一部分連接結果,則該提示將不起任何作用。

NO_PUSH_SUBQ

使用該提示將引導優化器將不能實現合并的子查詢放在最后執行。在子查詢無法縮減主查詢的查詢范圍,或者執行子查詢開銷較大的情況下,將這樣的子查詢放在最后執行可以在某種程度上提高整體的執行效率。也就是說,盡可能地使用其他查詢條件最大程度地縮減查詢范圍之后,再執行子查詢。

4、和表連接順序相關的

這些提示可以調整表連接的順序。調整表連接的順序并不是只能使用這些提示,在嵌套循環連接方式中也可以讓提示來引導優化器使用由驅動查詢條件所創建的索引。然而,該方法只有在使用的索引和表連接順序同時被調整的情況下才比較有效。一般而言,這些提示主要在執行多表連接和表之間的連接順序比較混亂的情況下才使用,也在排序合并連接或哈希連接方式下,為引導優化器優先執行數據量比較少得表時使用。

LEADING

在一個多表關聯的查詢中,這個 Hint 指定由哪個表作為驅動表,即告訴優化器首先要訪問那個表上的數據。引導優化器使用 LEADING 指定的表作為表連接順序中的第一個表。該提示既與 FROM 中所描述的表的順序無關,也與作為調整表連接順序的 ORDERED 提示不同,并且在使用該提示時并不需要調整 FROM 中所描述的表的順序。當該提示與 ORDERED 提示同時使用時,該提示被忽略。

這個提示類似 ORDERED 提示,它允許指定驅動查詢的表,然后由優化器來判斷下一個要訪問的表。如果使用這個提示指定多張表,那么就可以忽略這個提示。

ORDERED

引導優化器按照 FROM 中所描述的表的順序執行連接。如果和 LEADING 提示被一起使用,則 LEADING 提示將被忽略。由于 ORDERED 只能調整表連接的順序并不能改變表連接的方式,所以為了改變表的連接方式,經常將 USE_NL、USE_MERGE 提示與 ORDERED 提示放在一起使用。

5、和表連接操作相關的

USE_NL

使用該提示引導優化器按照嵌套循環連接方式執行表連接。它只是指出表連接的方式,對于表連接順序不會有任何影響。

USE_MERGE

引導優化器按照排序合并連接方式執行連接。在有必要的情況下,推薦將該提示與 ORDERED 提示一起使用。提示通常用于獲得查詢的最佳吞吐量。假設將兩個表連接在一起,從每個表返回的行集將被排序,然后再被合并(也就是合并排序),從而組成最終的結果集。由于每個行先被排序之后才進行合并,所以在給定查詢中檢索所有行時,速度將會最快。如果需要以最快速度返回第一行,就應該使用 USE_NL 提示。

USE_HASH

該提示引導優化器按照哈希連接方式執行連接。在執行哈希連接時,如果由于某一邊的表比較小,從而可以在內存中實現哈希連接,那么就能夠獲得非常好的執行速度。由于在大部分情況下優化器會通過對統計信息的分析來決定 Build Input 和 Prove Input,所以建議不要使用 ORDERED 提示隨意改變表的連接順序。但是當優化器沒能做出正確判斷時,或者像從嵌套視圖中所獲得的結果集合那樣不具備統計信息時,可以使用該提示。

6、和并行相關的

PARALLEL

指定 SQL 執行的并行度,這個值將會覆蓋表自身設定的并行度。如果這個值為 default,CBO 使用系統參數。從表中讀取大量數據和執行 DML 操作時使用該提示來指定 SQL 的并行操作。

一般情況下需要在該提示中指定將要使用的并行線程個數。如果在該提示中沒有指定并行度的個數,則優化器將使用 PARALLEL_THREADS_PER_CPU 參數所指定的值進行自動計算。如果在定義表時指定了 PARALLEL,那么在能夠使用并行操作的情況下,即使沒有使用該提示,優化器也會按照指定的并行級別選擇并行操作。

但是如果想在 DELETE、INSERT、UPDATE、MERGE 等 DML 操作中使用并行操作,則必須要在會話中設置 ALTER SESSION ENABLE PARALLEL DML。在某個會話中所設置的并行級別也可以被引用在內部的 GROUP BY 或者排序操作中。在并行操作中如果出現了某個限制要素,則該提示將被忽略。

NOPARALLEL/NO_PARALLEL

在 SQL 語句禁止使用并行。在有些版本中用 NO_PARALLEL 提示來代替 NOPARALLEL 提示。

PQ_DISTRIBUTE

為了提高并行連接的執行速度,使用該提示來定義使用何種方法在主從進程之間 (例如生產者進程和消費者進程) 分配各連接表的數據行。

PARALLEL_INDEX

為了按照并行操作的方式對分區索引進行索引范圍掃描而使用該提示,并且可以指定進程的個數。

7、其他相關的

APPEND

讓數據庫以直接加載的方式 (direct load) 將數據加載入庫。這個提示不會檢查當前是否有插入所需要的塊空間,相反它會直接將數據添加到新塊中。這樣會浪費空間,但可以提高插入的性能。需要注意的是,數據將被存儲在 HWM 之上的位置。

APPEND_VALUES

在 11.2 中,Oracle 新增了 APPEND_VALUES 提示,使得 INSERT INTO VALUES 語句也可以使用直接路徑插入。

CACHE

在全表掃描之后,數據塊將留在 LRU 列表的最活躍端。如果設置表的 CACHE 屬性,它的作用和 HINT 一樣。這個提示會將全表掃描全部緩存到內存中。如果表很大,會占用大量內存。因此適用于用戶經常訪問的較小的表。

NOCACHE

引導優化器將通過全表掃描方式獲取的數據塊緩存在 LRU 列表的最后位置,這樣可以讓數據庫實例緩存中的這些數據塊被優先清除。這是優化器在 Buffer Cache 中管理數據塊的默認方法(僅針對全表掃描)。

QB_NAME

使用該提示為查詢語句塊命名,在其他查詢語句塊可以直接使用該查詢語句塊的名稱。

DRIVING_SITE

這個提示在分布式數據庫操作中有用。指定表是處理連接所在的位置。可以限制通過網絡處理的信息量。此外,還可以建立遠程表的本地視圖來限制從遠程站點檢索的行。本地視圖應該有 where 子句,從而視圖可以在將行發送回本地數據庫之前限制從遠程數據庫返回的行。

DYNAMIC_SAMPLING

提示 SQL 執行時動態采樣的級別。這個級別為 0~10,它將覆蓋系統默認的動態采樣級別。等級越高,所獲得統計信息的準確率越高。該提示的功能就是為了確保將動態采樣原理應用在單個 SQL 中。

AND_EQUAL

這個提示會使優化器合并表上的多個索引,而不是選擇其中最好的索引(這是 INDEX 提示的用途)。這個提示與前面的 INDEX_JOIN 提示有區別,以此指定的合并索引隨后需訪問表,而 INDEX_JOIN 提示則只需訪問索引。如果發現需經常用到這個提示,可能需要刪除這些單個索引而改用一個組合索引。需要查詢條件里面包括所有索引列,然后取得每個索引中得到的 rowid 列表。然后對這些對象做 merge join,過濾出相同的 rowid 后再去表中獲取數據或者直接從索引中獲得數據。在 10g 中,and_equal 已經廢棄了,只能通過 hint 才能生效。

CARDINALITY

向優化器提供對某個查詢語句的整體或部分的預測基數值,并通過參考該基數值來為查詢語句制定執行計劃。如果在該提示中沒有指定表的名稱,則該基數值將被視為從該查詢語句所獲得的最終結果行數。

四、Hint 使用示例

下面通過一個例子說明一下提示的使用及在什么情況下提示會被忽略。

1、構建表

2、使用 INDEX 提示

* 在某些情況下,如果 CBO 認為 Hint 會導致錯誤結果,那么 Hint 則會忽略。該例子中因為 ID 字段可能為空,而索引是保存空值的,因此 count(*)使用索引將導致錯誤的結果,故而使用了全表掃描,忽略了 Hint。

3、使用 INDEX 提示(非空字段)

*ID 字段不可為空,因此 COUNT 可用索引掃描的方式處理,Hint 生效了。

到此,相信大家對“怎么正確使用 Oracle Hint”有了更深的了解,不妨來實際操作一番吧!這里是丸趣 TV 網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-24發表,共計8346字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 建始县| 上饶县| 宁化县| 内丘县| 桂平市| 特克斯县| 天台县| 通渭县| 哈密市| 丰台区| 崇信县| 永宁县| 道孚县| 大英县| 天全县| 南安市| 西和县| 炎陵县| 盘山县| 陇西县| 许昌县| 孝义市| 恩施市| 毕节市| 牙克石市| 西乌| 蛟河市| 吉首市| 营口市| 黄陵县| 莲花县| 珠海市| 西畴县| 肥乡县| 乌兰察布市| 大冶市| 鹤山市| 屏南县| 滕州市| 星子县| 乐都县|