Hint 应该少用,仅在您收集了相关表的统计信息并且使用 语句在没有 Hint 的情况下评估了优化器计划之后,才谨慎考虑使用。更改数据库条件以及在后续版本中增强查询性能可能会导致您代码中的 Hint 对性能产生重大影响。

一个语句块只能有一个注释包含 Hint,并且该注释必须跟随 SELECTUPDATEINSERTMERGEDELETE 关键字。

以下是 Hint 在语句块注释中的语法格式:

Hint 从语法上看是一种特殊的 SQL 注释, 所不同的是在注释的左标记后增加了一个加号(+)。 如果服务器端无法识别 SQL 语句中的 Hint,那么优化器会选择忽略用户指定的 Hint 而使用默认计划所生成逻辑。另外需要指明的是,Hint 只影响优化器所生成的计划的逻辑,而不影响 SQL 语句的语义。

以下是定义 Hint 时需要注意的一些规则:

  • Hint 包含拼写错误或语法错误时会被忽略。但是,数据库会考虑在同一注释中其他正确指定的 Hint。

  • Hint 的组合相互冲突时 Hint 无效。但是,数据库会在同一注释中考虑其他不冲突的 Hint。

  • 数据库环境使用 PL/SQL 版本 1 时 Hint 无效,例如 Forms 版本 3 触发器。

您可以通过在许多 Hint 中定义一个可选的查询块名称,以此来指定该 Hint 适用的查询块。使用此语法,允许您在外部查询中指定一个应用于嵌入式视图的 Hint。

查询块参数的语法格式为 @queryblock,其中 queryblock 是在查询中被指定的查询块的标识符。queryblock 标识符可以是系统生成的,也可以是用户自己指定的。当您在查询块中直接指定要应用的 Hint 时,将忽略 @queryblock

  • 可以使用 来指定用户自定义的名称。

许多 Hint 既可以应用于特定的表或索引,也可以更全局地应用于视图中的表或一部分索引的列。语法元素 tablespecindexspec 定义了这些全局 Hint。

以下是 tablespec 的语法:

您必须完全按照在语句中显示的方式来指定要访问的表。如果该语句使用表的别名,则在 Hint 中使用也使用别名而不是表名。但是,即使 Schema 名称出现在语句中,也不要在 Hint 中使用的表名中包含 Schema 名称。

注意

使用 tablespec 子句指定全局 Hint 对于使用 ANSI 连接的查询不起作用,因为优化器在解析期间会生成额外的视图。相反,可以通过 @queryblock 来指定该提示所应用到的查询块。

在 Hint 的说明部分,当 tablespec 后跟着 indexspec 时,允许但不要求使用逗号来分隔表名和索引名。也允许(但不是必需)使用逗号分隔多次出现的 。