Leading Hint是一個能指定超過一個表的多表Hint,Leading Hint指導最佳化器先按照Leading Hint指定的部分表的順序進行Join,然後再將Join完成的表作為最先訪問的表與剩餘的其他表進行Join。
注意事項
- 目前暫未支援在嵌套SQL語句中使用Leading Hint,請勿在子類語句中使用Leading Hint,否則會產生不可預期的結果。
- 最佳化器在產生多表Join順序時,對於有串連條件的表,會盡量先嘗試與其有串連關係的表Join,如果這其中沒有可以執行路徑產生,才會去嘗試產生Cartesian Product。因此,在使用Leading Hint時,對於有Join條件的表,緊跟著的表應儘可能是與前表有相關Join條件的表。否則,最佳化器會因為無法產生執行路徑而忽略Leading Hint。
前提條件
PolarDB PostgreSQL版(相容Oracle)預設開啟支援Hints功能,可以執行以下命令開啟該功能:
set enable_hints = true;
文法
- Hints注釋以
/*+
開始(*
和+
之間不能有空格),以*/
結束。 - 提示句包括提示名和接下來括弧包含的參數,以空格作為分界。
- 需要緊跟在SELECT、UPDATE、INSERT、MERGE或DELETE關鍵字之後使用。
- 不區分Hints指令的大小寫,即指令大寫或小寫形式都能正常工作。
說明 出現以下情況時,會發生衝突,導致Leading Hint不生效。
- 當指定的表因為依賴關係等原因無法按照指示的順序先進行Join時,會忽略掉Leading Hint。
- 當同時存在兩個或多個Leading Hint時,會忽略掉所有的Leading Hint。
- 當Ordered Hint與Leading Hint同時存在時,Ordered Hint會覆蓋掉所有Leading Hint。
- 當指定的表名或者別名中含有'.'時,例如,"s.t",會忽略掉Leading Hint。
- 沒有緊跟在SELECT,UPDATE,INSERT,MERGE或DELETE關鍵字之後,會忽略掉Leading Hint。
樣本
假設資料庫中存在四張表, 四張表的表名或者別名為a b c d,且任意兩表之間都可以進行串連。
- 正確的文法
樣本 可能串連路徑 /*+ leading(a) */ (((a b) c) d), (((a b) d) c), (((a c) b) d), (((a c) d) b), (((a d) b) c), (((a c) c) b) /*+ leading(a b) */ (((a b) c) d), (((a b) d) c) /*+ leading(a b c) */ (((a b) c) d) /*+ leading(a b c d) */ (((a b) c) d) 說明((a b) c)
表示a b c三張表的Join順序為a->b->c
,(c (a b))
表示a b c三張表的Join順序為c->a->b
。 - 錯誤的文法樣本如下所示:
- /* + leading(a) */
- /*+ leading(a b) leading(a b) */
- /*+ leading(a b a) */
- /*+ leading(a b) leading(a)*/
- /*+ leading(a b) leading(c d) */
- /*+ leading(a b e) */
- *+ leading(a b) leading(a c) */
- /*+ leading() */
說明 資料庫中不存在表名或別名為e的表。