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的表。