溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

SQL優(yōu)化:一文說清Oracle Hint的正確使用姿勢

發(fā)布時(shí)間:2020-06-24 16:18:18 來源:網(wǎng)絡(luò) 閱讀:455 作者:宜信技術(shù) 欄目:關(guān)系型數(shù)據(jù)庫

一、提示(Hint)概述

1、為什么引入Hint?

Hint是Oracle數(shù)據(jù)庫中很有特色的一個(gè)功能,是很多DBA優(yōu)化中經(jīng)常采用的一個(gè)手段。那為什么Oracle會(huì)考慮引入優(yōu)化器呢?基于代價(jià)的優(yōu)化器是很聰明的,在絕大多數(shù)情況下它會(huì)選擇正確的優(yōu)化器,減輕DBA的負(fù)擔(dān)。

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

2、不要過分依賴Hint

當(dāng)遇到SQL執(zhí)行計(jì)劃不好的情況,應(yīng)優(yōu)先考慮統(tǒng)計(jì)信息等問題,而不是直接加Hint了事。如果統(tǒng)計(jì)信息無誤,應(yīng)該考慮物理結(jié)構(gòu)是否合理,即沒有合適的索引。只有在最后仍然不能SQL按優(yōu)化的執(zhí)行計(jì)劃執(zhí)行時(shí),才考慮Hint。

畢竟使用Hint,需要應(yīng)用系統(tǒng)修改代碼,Hint只能解決一條SQL的問題,并且由于數(shù)據(jù)分布的變化或其他原因(如索引更名)等,會(huì)導(dǎo)致SQL再次出現(xiàn)性能問題。

3、Hint的弊端

  • Hint是比較"暴力"的一種解決方式,不是很優(yōu)雅。需要開發(fā)人員手工修改代碼。

  • Hint不會(huì)去適應(yīng)新的變化。比如數(shù)據(jù)結(jié)構(gòu)、數(shù)據(jù)規(guī)模發(fā)生了重大變化,但使用Hint的語句是感知變化并產(chǎn)生更優(yōu)的執(zhí)行計(jì)劃。

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

4、Hint與注釋關(guān)系

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

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

5、Hint功能

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

  • 優(yōu)化器類型

  • 優(yōu)化器優(yōu)化目標(biāo)

  • 數(shù)據(jù)讀取方式(訪問路徑)

  • 查詢轉(zhuǎn)換類型

  • 表間關(guān)聯(lián)的順序

  • 表間關(guān)聯(lián)的類型

  • 并行特性

  • 其他特性

二、Hint用法

1、語法

SQL優(yōu)化:一文說清Oracle Hint的正確使用姿勢

1)關(guān)鍵字說明
  • DELETE、INSERT、SELECT和UPDATE是標(biāo)識(shí)一個(gè)語句塊開始的關(guān)鍵字,包含提示的注釋只能出現(xiàn)在這些關(guān)鍵字的后面,否則提示無效。

  • "+"號(hào)表示該注釋是一個(gè)提示,該加號(hào)必須立即跟在"/*"的后面,中間不能有空格。

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

  • text是其它說明hint的注釋性文本
2)提示中的錯(cuò)誤

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

  • explain plan + dbms_xplan

使用dbms_xplan輸出中的note選項(xiàng)。

  • 10132事件

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

3)提示中的對象

SELECT /+ INDEX(table_name index_name) / ...

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

  • index_name可以不必寫,Oracle會(huì)根據(jù)統(tǒng)計(jì)值選一個(gè)索引。

  • 如果索引名或表名寫錯(cuò)了,那這個(gè)hint就會(huì)被忽略。

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

一個(gè)很常見的錯(cuò)誤時(shí),在使用提示的時(shí)候最易犯的錯(cuò)誤是與表的別名有關(guān)。正確的規(guī)則是,當(dāng)在提示中使用表時(shí),只要表有別名就應(yīng)該使用別名而不是表名。

2、提示的作用域

  • 查詢塊

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

SQL優(yōu)化:一文說清Oracle Hint的正確使用姿勢

  • 例外 - 全局提示

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

SQL優(yōu)化:一文說清Oracle Hint的正確使用姿勢

  • 命名查詢塊

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

SQL優(yōu)化:一文說清Oracle Hint的正確使用姿勢

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

3、提示數(shù)據(jù)字典

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

SQL優(yōu)化:一文說清Oracle Hint的正確使用姿勢

  • INVERSE

這個(gè)hint相反操作的hint。

  • VERSION

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

三、Hint分類

1、和優(yōu)化器相關(guān)的

當(dāng)對優(yōu)化器為某個(gè)語句所制定的基本執(zhí)行計(jì)劃不滿意時(shí),最好的辦法就是通過提示來轉(zhuǎn)換優(yōu)化器的模式,并觀察其轉(zhuǎn)換后的結(jié)果,看是否已經(jīng)達(dá)到期望程度。如果只通過轉(zhuǎn)換優(yōu)化器的模式就可以獲得非常好的執(zhí)行計(jì)劃,則就沒有必要額外使用更為復(fù)雜的提示了。

  • OPT_PARAM

這個(gè)提示的作用就是使我們在某條語句中指定某個(gè)系統(tǒng)參數(shù)值。

  • ALL_ROWS

為實(shí)現(xiàn)查詢語句整體最優(yōu)化而引導(dǎo)優(yōu)化器制定最少成本的執(zhí)行計(jì)劃。這個(gè)提示會(huì)使優(yōu)化器選擇一條可最快檢索所有查詢行的路徑,而代價(jià)就是在檢索一行數(shù)據(jù)時(shí),速度很慢。

  • FIRST_ROWS

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

  • CHOOSE

依據(jù)SQL中所使用到的表的統(tǒng)計(jì)信息存在與否,來決定使用RBO還是CBO。在CHOOSE模式下,如果能夠參考表的統(tǒng)計(jì)信息,則將按照ALL_ROWS方式執(zhí)行。除非在查詢中的所有表都沒有經(jīng)過分析,否則choose提示會(huì)對整個(gè)查詢使用基于代價(jià)的優(yōu)化。如果在多表連接中有一個(gè)表經(jīng)過分析過,那么就會(huì)對整個(gè)查詢進(jìn)行基于代價(jià)的優(yōu)化。

  • RULE

使用基于規(guī)則的優(yōu)化器來實(shí)現(xiàn)最優(yōu)化執(zhí)行,即引導(dǎo)優(yōu)化器根據(jù)優(yōu)先順序規(guī)則來決定查詢條件中所使用到的索引或運(yùn)算符的執(zhí)行順序來制定執(zhí)行計(jì)劃。這個(gè)提示強(qiáng)制oracle優(yōu)先使用預(yù)定義的一組規(guī)則,而不是對數(shù)據(jù)進(jìn)行統(tǒng)計(jì);同時(shí)該提示還會(huì)使這個(gè)語句避免使用其他提示,除了DRIVING_SITE和ORDERED(不管是否進(jìn)行基于規(guī)則的優(yōu)化,這兩個(gè)提示都可使用)。

2、和訪問路徑相關(guān)的

  • FULL

告訴優(yōu)化器通過全表掃描方式訪問數(shù)據(jù)。這個(gè)提示只對所指定的表進(jìn)行全表掃描,而不是查詢中的所有表。FULL提示可以改善性能。這主要是因?yàn)樗淖兞瞬樵冎械尿?qū)動(dòng)表,而不是因?yàn)槿頀呙?。在使用其他某些提示時(shí),也必須使用FULL提示。只有訪問整個(gè)表時(shí),才可利用CACHE提示將表進(jìn)行緩存。并行組中的某些提示也必須使用全表掃描。

  • CLUSTER

引導(dǎo)優(yōu)化器通過掃描聚簇索引來從索引表中讀取數(shù)據(jù)。

  • HASH

引導(dǎo)優(yōu)化器按照哈希掃描的方式從表中讀取數(shù)據(jù)。

  • INDEX

告訴優(yōu)化器對指定表通過索引的方式訪問數(shù)據(jù)。當(dāng)訪問數(shù)據(jù)會(huì)導(dǎo)致結(jié)果集不完整時(shí),優(yōu)化器將忽略這個(gè)Hint。

  • NO_INDEX

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

  • INDEX_ASC

利用索引從表中讀取數(shù)據(jù)時(shí),引導(dǎo)優(yōu)化器對提示中所指定索引的索引列值按照升序使用范圍掃描。

  • INDEX_COMBINE

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

  • INDEX_JOIN

索引關(guān)聯(lián),當(dāng)謂詞中引用的列上都有索引的時(shí)候,可以通過索引關(guān)聯(lián)的方式來訪問數(shù)據(jù)。這個(gè)提示可以將同一個(gè)表的各個(gè)不同索引進(jìn)行合并,這樣就只需要訪問這些索引就可以了,節(jié)省了回表查詢的時(shí)間。但只能在基于代價(jià)的優(yōu)化器中使用該提示。這個(gè)提示不僅允許只訪問表上的索引,這樣可以掃描更少的代碼塊,并且它比使用索引并通過rowid掃描整個(gè)表快5倍。

  • INDEX_DESC

利用索引從表中讀取數(shù)據(jù)時(shí),引導(dǎo)優(yōu)化器對提示中所指定索引的索引列值按照降序使用范圍掃描。

  • INDEX_FFS

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

  • INDEX_SS

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

3、和查詢轉(zhuǎn)換相關(guān)的

  • USE_CONCAT

將含有多個(gè)OR或者IN運(yùn)算符所連接起來的查詢語句分解為多個(gè)單一查詢語句,并為每個(gè)單一查詢語句選擇最優(yōu)化查詢路徑,然后再將這些最優(yōu)化查詢路徑結(jié)合在一起,以實(shí)現(xiàn)整體查詢語句的最優(yōu)化目的。只有在驅(qū)動(dòng)查詢條件中包含OR的時(shí)候,才可以使用該提示。

  • NO_EXPAND

引導(dǎo)優(yōu)化器不要為使用OR運(yùn)算符號(hào)(或IN運(yùn)算符)的條件制定相互結(jié)合的執(zhí)行計(jì)劃。正好和USE_CONCAT相反。

  • REWRITE

當(dāng)表連接的對象是數(shù)據(jù)量比較大的表或者需要獲得使用統(tǒng)計(jì)函數(shù)處理過的結(jié)果時(shí),為了提高執(zhí)行速度可預(yù)先創(chuàng)建物化視圖。當(dāng)用戶要求查詢某個(gè)查詢語句時(shí),優(yōu)化器會(huì)在從表中和從物化視圖中讀取數(shù)據(jù)的兩種方法中選擇一個(gè)更有效的方法來讀取數(shù)據(jù)。該執(zhí)行方法稱之為查詢重寫。使用REWRITE提示引導(dǎo)優(yōu)化器按照該方式執(zhí)行。

  • MERGE

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

  • UNNEST

提示優(yōu)化器將子查詢轉(zhuǎn)換為連接的方式。也就是引導(dǎo)優(yōu)化器合并子查詢和主查詢并且將其向連接類型轉(zhuǎn)換。

  • NO_UNNEST

引導(dǎo)優(yōu)化器讓子查詢能夠獨(dú)立地執(zhí)行完畢之后再跟外圍的查詢做FILTER。

  • PUSH_PRED

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

  • NO_PUSH_PRED

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

  • PUSH_SUBQ

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

  • NO_PUSH_SUBQ

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

4、和表連接順序相關(guān)的

這些提示可以調(diào)整表連接的順序。調(diào)整表連接的順序并不是只能使用這些提示,在嵌套循環(huán)連接方式中也可以讓提示來引導(dǎo)優(yōu)化器使用由驅(qū)動(dòng)查詢條件所創(chuàng)建的索引。然而,該方法只有在使用的索引和表連接順序同時(shí)被調(diào)整的情況下才比較有效。一般而言,這些提示主要在執(zhí)行多表連接和表之間的連接順序比較混亂的情況下才使用,也在排序合并連接或哈希連接方式下,為引導(dǎo)優(yōu)化器優(yōu)先執(zhí)行數(shù)據(jù)量比較少得表時(shí)使用。

  • LEADING

在一個(gè)多表關(guān)聯(lián)的查詢中,這個(gè)Hint指定由哪個(gè)表作為驅(qū)動(dòng)表,即告訴優(yōu)化器首先要訪問那個(gè)表上的數(shù)據(jù)。引導(dǎo)優(yōu)化器使用LEADING指定的表作為表連接順序中的第一個(gè)表。該提示既與FROM中所描述的表的順序無關(guān),也與作為調(diào)整表連接順序的ORDERED提示不同,并且在使用該提示時(shí)并不需要調(diào)整FROM中所描述的表的順序。當(dāng)該提示與ORDERED提示同時(shí)使用時(shí),該提示被忽略。

這個(gè)提示類似ORDERED提示,它允許指定驅(qū)動(dòng)查詢的表,然后由優(yōu)化器來判斷下一個(gè)要訪問的表。如果使用這個(gè)提示指定多張表,那么就可以忽略這個(gè)提示。

  • ORDERED

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

5、和表連接操作相關(guān)的

  • USE_NL

使用該提示引導(dǎo)優(yōu)化器按照嵌套循環(huán)連接方式執(zhí)行表連接。它只是指出表連接的方式,對于表連接順序不會(huì)有任何影響。

  • USE_MERGE

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

  • USE_HASH

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

6、和并行相關(guān)的

  • PARALLEL

指定SQL執(zhí)行的并行度,這個(gè)值將會(huì)覆蓋表自身設(shè)定的并行度。如果這個(gè)值為default,CBO使用系統(tǒng)參數(shù)。從表中讀取大量數(shù)據(jù)和執(zhí)行DML操作時(shí)使用該提示來指定SQL的并行操作。

一般情況下需要在該提示中指定將要使用的并行線程個(gè)數(shù)。如果在該提示中沒有指定并行度的個(gè)數(shù),則優(yōu)化器將使用PARALLEL_THREADS_PER_CPU參數(shù)所指定的值進(jìn)行自動(dòng)計(jì)算。如果在定義表時(shí)指定了PARALLEL,那么在能夠使用并行操作的情況下,即使沒有使用該提示,優(yōu)化器也會(huì)按照指定的并行級(jí)別選擇并行操作。

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

  • NOPARALLEL/NO_PARALLEL

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

  • PQ_DISTRIBUTE

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

  • PARALLEL_INDEX

為了按照并行操作的方式對分區(qū)索引進(jìn)行索引范圍掃描而使用該提示,并且可以指定進(jìn)程的個(gè)數(shù)。

7、其他相關(guān)的

  • APPEND

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

  • APPEND_VALUES

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

  • CACHE

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

  • NOCACHE

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

  • QB_NAME

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

  • DRIVING_SITE

這個(gè)提示在分布式數(shù)據(jù)庫操作中有用。指定表是處理連接所在的位置??梢韵拗仆ㄟ^網(wǎng)絡(luò)處理的信息量。此外,還可以建立遠(yuǎn)程表的本地視圖來限制從遠(yuǎn)程站點(diǎn)檢索的行。本地視圖應(yīng)該有where子句,從而視圖可以在將行發(fā)送回本地?cái)?shù)據(jù)庫之前限制從遠(yuǎn)程數(shù)據(jù)庫返回的行。

  • DYNAMIC_SAMPLING

提示SQL執(zhí)行時(shí)動(dòng)態(tài)采樣的級(jí)別。這個(gè)級(jí)別為0~10,它將覆蓋系統(tǒng)默認(rèn)的動(dòng)態(tài)采樣級(jí)別。等級(jí)越高,所獲得統(tǒng)計(jì)信息的準(zhǔn)確率越高。該提示的功能就是為了確保將動(dòng)態(tài)采樣原理應(yīng)用在單個(gè)SQL中。

  • AND_EQUAL

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

  • CARDINALITY

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

四、Hint使用示例

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

1、構(gòu)建表

SQL優(yōu)化:一文說清Oracle Hint的正確使用姿勢

2、使用INDEX提示

SQL優(yōu)化:一文說清Oracle Hint的正確使用姿勢

*在某些情況下,如果CBO認(rèn)為Hint會(huì)導(dǎo)致錯(cuò)誤結(jié)果,那么Hint則會(huì)忽略。該例子中因?yàn)镮D字段可能為空,而索引是保存空值的,因此count(*)使用索引將導(dǎo)致錯(cuò)誤的結(jié)果,故而使用了全表掃描,忽略了Hint。

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

SQL優(yōu)化:一文說清Oracle Hint的正確使用姿勢

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

作者:韓鋒

來源:宜信技術(shù)學(xué)院 (http://college.creditease.cn/)

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI