首批通过分布式安全可靠测评,为关键业务系统打造
Hint 概述
更新时间:2026-04-10 12:01:01
Hint 是一种 SQL 语句注释,用于将指令传递给 OceanBase 数据库优化器。通过 Hint 可以使优化器生成指定的执行计划。
一般情况下,优化器会为用户查询选择最佳的执行计划,不需要用户使用 Hint 指定,但在某些场景下,优化器生成的执行计划可能无法满足用户的要求,这时就需要用户使用 Hint 来主动指定并生成特殊的执行计划。
Hint 应该尽量少用,在收集了相关表的统计信息并且在没有 Hint 的情况下使用 EXPLAIN PLAN 语句评估了优化器计划之后,才建议用户谨慎考虑使用 Hint。更改数据库条件以及在后续版本中增强查询性能可能会导致您代码中的 Hint 对性能产生重大影响。
Hint 的使用
一条语句只能包含一个 Hint 注释,并且该注释必须跟随 CREATE、SELECT、UPDATE、INSERT、REPLACE 或 DELETE 关键字。
Hint 在语句注释中的语法格式如下:
{CREATE|DELETE|INSERT|SELECT|UPDATE|REPLACE} /*+ hint_text [,hint_text...] */
Hint 从语法上看是一种特殊的 SQL 注释,所不同的是在注释的左标记后增加了一个加号(+)。如果服务器端无法识别 SQL 语句中的 Hint,那么优化器会选择忽略用户指定的 Hint 而使用默认计划所生成的执行逻辑。另外需要指明的是,Hint 只影响优化器所生成的执行计划的逻辑,而不影响 SQL 语句的语义。
以下是定义 Hint 时需要注意的一些规则:
加号(+)使数据库将注释解释为 Hint 列表。加号必须紧跟在注释左标记符后,不允许有空格。
加号(+)和 Hint 文本之间的空格是可选的。如果注释中包含多个 Hint,则 Hint 间至少用一个空格进行分隔。
Hint 包含拼写错误或语法错误时会被忽略。但是,数据库会考虑在同一注释中使用其他正确指定的 Hint。
不跟随
CREATE、DELETE、INSERT、REPLACE、SELECT或UPDATE关键字的 Hint 无效。Hint 的组合相互冲突时 Hint 无效。但是,数据库会在同一注释中考虑使用其他不冲突的 Hint。
在 Hint 中定义查询块
您可以通过在许多 Hint 中定义一个可选的查询块名称,以此来指定该 Hint 适用的查询块。
使用此语法,允许您在外部查询中指定一个应用于嵌入式视图的 Hint。
查询块参数的语法格式为 @queryblock,其中 queryblock 是在查询中被指定的查询块的标识符。queryblock 标识符可以是系统生成的,也可以是用户自己指定的。当您在查询块中直接指定要应用的 Hint 时,将忽略 @queryblock。
系统生成的标识符可以通过对查询使用
EXPLAIN生成。可以使用 QB_NAME 来指定用户自定义的名称。
定义全局 Hint
许多 Hint 既可以应用于特定的表或索引,也可以更全局地应用于视图中的表或一部分索引的列。语法元素 tablespec 和 indexspec 定义了这些全局 Hint。
tablespec 的语法如下:
[ view.[,view. ]... ] table_name
您必须完全按照在语句中显示的方式来指定要访问的表。如果该语句使用表的别名,则在 Hint 中也使用别名而不是表名。但是,即使 Schema 名称出现在语句中,也不要在 Hint 中使用的表名中包含 Schema 名称。
注意
使用 tablespec 子句指定全局 Hint 对于使用 ANSI 连接的查询不起作用,因为优化器在解析期间会生成额外的视图。相反,可以通过 @queryblock 来指定该 Hint 所应用到的查询块。
indexspec 的语法如下:
{ index
| ( [ table. ]column_name [ [ table. ]column_name ]...)
}
在 Hint 的说明部分,当 tablespec 后跟着 indexspec 时,允许但不要求使用逗号来分隔表名和索引名。另外也允许(但不是必需)使用逗号分隔多次出现的 indexspec。