HINT的作用及书写要求
  IE5LYMWlmdvL 2023年11月02日 42 0

什么是HINT及其作用

HINT(提示)是出现在SQL语句的特定位置的一种特殊注释,它主要用于向Oracle数据库优化器传递指令,从而为SQL选择特定的执行计划。但是,当优化器无法按照HINT生成特定的执行计划时,它会忽略HINT。另外,也不是所有的HINT都是影响优化器和执行计划的。比如GATHER_PLAN_STATISTICS、MONITOR等提示。
“出现在SQL语句的特定位置”是指HINT必须紧跟在如下关键字的后面:SELECT, UPDATE, INSERT, MERGE, DELETE;
“一种特殊注释”是指其书写的方法,与一般注释不同。一般的注释是以/
* */或 -- 来标记,而HINT是使用 /*+ */ 和 --+ (多了一个加号)的方式来书写。正是多的这一个加号,使其从注释,华丽地转身成为影响优化器行为的HINT。注意--+的这种写法,会导致其后这一行上的所有字符,都被认为是HINT,所以,如果并不是这样,注意将HINT内容与其它代码写到不同行上。

可以通过查询数据字典v$sql_hint来获取完整的HINT内容。

此外,HINT的书写,也有一定的要求,如果违反了相关要求,会导致HINT部分或全部失效。具体要求如下:

  • “+”(加号)必须紧跟在注释分隔符(即/*或--)之后,中间不能有空格。
  • HINT与HINT之间,至少要有一个空格。
  • 对于可以引用具体对象的HINT,在引用具体对象时,不可以指定其属主名。
  • 当SQL中的表存在别名时,在HINT中对其引用时,只可以引用别名。
  • 相互矛盾的HINT会被弃用,而不是择一使用。
  • 如果在HINT中出现保留关键字,则保留关键字之后的HINT失效。

测试验证

下面,我们通过一些简单的示例,来展示HINT的作用,以及不同书写方式或错误,可能带来的影响。

示例1:HINT影响执行计划的行为

HINT的作用及书写要求_hint


如上图中红框所示,我们可以看到这条SQL的执行计划中,用到了索引。

我们可以通过添加适当的提示,改变执行计划,使其不使用索引,而是全表扫描。如下图所示:

HINT的作用及书写要求_执行计划_02

示例2:“+”号没有紧跟在注释分隔符之后,导致HINT失效

HINT的作用及书写要求_执行计划_03


如上图所示,HINT并没有发挥作用。而且,HINT书写错误,并不会导致报错,因为其形式上,就是注释。

示例3:HINT要跟在紧在如下关键字的后面:SELECT, UPDATE, INSERT, MERGE, DELETE,除空格外,不应用其它字符出现。

如下例中,就是在SELECT和HINT之间,出现了“*”号:

HINT的作用及书写要求_SQL_04

示例4:HINT中引用对象时,不可以指定其属主名。

比如前边示例中用到的表T1,其是DEMO用户下的表。如果我们在HINT中引用T1时,写成DEMO.T1,则会导致HINT失效。如下图所示:

HINT的作用及书写要求_SQL_05

示例5:HINT中引用的表,在SQL中存在别名时,要使用别名。

否则会导致HINT失效。如下图所示:

HINT的作用及书写要求_优化_06


引用表别名时,HINT是生效的。而不引用表别名时,HINT是失效的,如下图所示:

HINT的作用及书写要求_hint_07

示例6:相互矛盾的HINT会被均被弃用

如下图所示,我们使用相关提示,让执行计划对目标索引使用快速全扫的访问方式:

HINT的作用及书写要求_优化_08

同时,我们也可以继续使用前边全表扫描的HINT,让执行计划不使用索引,如下图所示:

HINT的作用及书写要求_SQL_09

但是,当我们将上述两个HINT同时写到一起时,则两个HINT均被弃用了。结果是在哪个都没用。如下图所示(注意,虽然使用了目标索引,但访问的方法不是快速全扫,而是范围扫描):

HINT的作用及书写要求_hint_10

示例7:保留关键字之后的HINT会失效

保留关键字的清单,可以查询v$reserved_words数据字典。其中“create”就是其中的一个保留关键字。当我们把它写到HINT的前面,则后面的HINT就失效了。如下图所示:

HINT的作用及书写要求_SQL_11

当我们把它写到中间时,则前边的HINT有效,后边的则失效。如下图所示:

HINT的作用及书写要求_优化_12


如上所示,在前边的测试中,我们知道,这两个HINT是相互矛盾的,应该都会被弃用,但这里的结果,可以看到,是保留关键字后面的HINT失效了。这里要特别提醒,因为逗号也是保留关键字,所以,在书写HINT时,特别是多个HINT时,HINT与HINT之间,只要使用空格分隔,不要用逗号分隔。这也会导致第一个逗号之后的HINT失效。如下图所示:

HINT的作用及书写要求_SQL_13

但是,如果单个HINT中的参数支持使用逗号,则该逗号不影响后续的HINT。如下图所示:

HINT的作用及书写要求_优化_14

回顾总结

1、HINT可以影响SQL的执行计划和处理行为。
2、HINT需要出现在指定的位置(特定关键字SELECT, UPDATE, INSERT, MERGE, DELETE之后),并使用指定的写法(/*+ */ 或 --+)。
3、书写或使用HINT不当,会导致HINT失效。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  xaeiTka4h8LY   2024年05月31日   44   0   0 MySQLSQL
  xaeiTka4h8LY   2024年05月17日   51   0   0 数据库JavaSQL
  xaeiTka4h8LY   2024年05月17日   47   0   0 数据库SQL
  Dk8XksB4KnJY   2023年12月23日   32   0   0 字段字段SQLSQL
IE5LYMWlmdvL