OceanBase Hint概述

2021-06-17 16:41 更新

Hint 是 SQL 語句中將指令傳遞給 OceanBase 數(shù)據(jù)庫優(yōu)化器或服務(wù)器的一種注釋。通過 Hint 可以使優(yōu)化器或服務(wù)器生成某種特定的計(jì)劃。 一般情況下,優(yōu)化器會(huì)為用戶查詢選擇最佳的執(zhí)行計(jì)劃,不需要用戶主動(dòng)使用 Hint 指定,但在某些場(chǎng)景下,優(yōu)化器生成的執(zhí)行計(jì)劃可能不滿足用戶的要求,這時(shí)就需要用戶使用 Hint 來主動(dòng)指定并生成特殊的執(zhí)行計(jì)劃。

Hint 應(yīng)該少用,僅在您收集了相關(guān)表的統(tǒng)計(jì)信息并且使用 ?EXPLAIN PLAN? 語句在沒有 Hint 的情況下評(píng)估了優(yōu)化器計(jì)劃之后,才謹(jǐn)慎考慮使用。更改數(shù)據(jù)庫條件以及在后續(xù)版本中增強(qiáng)查詢性能可能會(huì)導(dǎo)致您代碼中的 Hint 對(duì)性能產(chǎn)生重大影響。

Hint 的使用

一個(gè)語句塊只能有一個(gè)注釋包含 Hint,并且該注釋必須跟隨 ?SELECT?、?UPDATE?、?INSERT?、?MERGE? 或 ?DELETE? 關(guān)鍵字。

以下是 Hint 在語句塊注釋中的語法格式:

/*+[hint text]*/

Hint 從語法上看是一種特殊的 SQL 注釋, 所不同的是在注釋的左標(biāo)記后增加了一個(gè)加號(hào)(+)。 如果服務(wù)器端無法識(shí)別 SQL 語句中的 Hint,那么優(yōu)化器會(huì)選擇忽略用戶指定的 Hint 而使用默認(rèn)計(jì)劃所生成邏輯。另外需要指明的是,Hint 只影響優(yōu)化器所生成的計(jì)劃的邏輯,而不影響 SQL 語句的語義。

以下是定義 Hint 時(shí)需要注意的一些規(guī)則:

  • 加號(hào)(+)使數(shù)據(jù)庫將注釋解釋為 Hint 列表。加號(hào)必須緊跟在注釋左標(biāo)記符后,不允許有空格。
  • 加號(hào)(+)和 Hint 文本之間的空格是可選的。如果注釋中包含多個(gè) Hint,則 Hint 間至少用一個(gè)空格進(jìn)行分隔。
  • Hint 包含拼寫錯(cuò)誤或語法錯(cuò)誤時(shí)會(huì)被忽略。但是,數(shù)據(jù)庫會(huì)考慮在同一注釋中其他正確指定的 Hint。
  • 不跟隨 ?DELETE?、?INSERT?、?MERGE?、?SELECT? 或 ?UPDATE? 關(guān)鍵字的 Hint 無效。
  • Hint 的組合相互沖突時(shí) Hint 無效。但是,數(shù)據(jù)庫會(huì)在同一注釋中考慮其他不沖突的 Hint。
  • 數(shù)據(jù)庫環(huán)境使用 PL/SQL 版本 1 時(shí) Hint 無效,例如 Forms 版本 3 觸發(fā)器。

在 Hint 中定義查詢塊

您可以通過在許多 Hint 中定義一個(gè)可選的查詢塊名稱,以此來指定該 Hint 適用的查詢塊。使用此語法,允許您在外部查詢中指定一個(gè)應(yīng)用于嵌入式視圖的 Hint。

查詢塊參數(shù)的語法格式為 ?@queryblock?,其中 ?queryblock? 是在查詢中被指定的查詢塊的標(biāo)識(shí)符。?queryblock? 標(biāo)識(shí)符可以是系統(tǒng)生成的,也可以是用戶自己指定的。當(dāng)您在查詢塊中直接指定要應(yīng)用的 Hint 時(shí),將忽略 ?@queryblock?。

  • 系統(tǒng)生成的標(biāo)識(shí)符可以通過對(duì)查詢使用 ?EXPLAIN PLAN? 生成,預(yù)轉(zhuǎn)換查詢塊的名稱可以通過對(duì)使用了 ?NO_QUERY_TRANSFORMATION? Hint 的查詢運(yùn)行 ?EXPLAIN PLAN? 生成。
  • 可以使用 ?QB_NAME? 來指定用戶自定義的名稱。

定義全局 Hint

許多 Hint 既可以應(yīng)用于特定的表或索引,也可以更全局地應(yīng)用于視圖中的表或一部分索引的列。語法元素 ?tablespec? 和 ?indexspec? 定義了這些全局 Hint。

以下是 ?tablespec? 的語法:

[ view.[ view. ]... ]table

您必須完全按照在語句中顯示的方式來指定要訪問的表。如果該語句使用表的別名,則在 Hint 中使用也使用別名而不是表名。但是,即使 Schema 名稱出現(xiàn)在語句中,也不要在 Hint 中使用的表名中包含 Schema 名稱。

注意 
使用 ?tablespec? 子句指定全局 Hint 對(duì)于使用 ANSI 連接的查詢不起作用,因?yàn)閮?yōu)化器在解析期間會(huì)生成額外的視圖。相反,可以通過 ?@queryblock? 來指定該提示所應(yīng)用到的查詢塊。

以下是? indexspec ?的語法:

{ index
| ( [ table. ]column [ [ table. ]column ]...)
}

在 Hint 的說明部分,當(dāng) ?tablespec? 后跟著 ?indexspec? 時(shí),允許但不要求使用逗號(hào)來分隔表名和索引名。也允許(但不是必需)使用逗號(hào)分隔多次出現(xiàn)的 ?indexspec?。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)