1、概述
- Hint是SQL语句注释,可向OceanBase数据库优化器传达指令,使优化器生成指定执行计划。
- 通常优化器会为查询选择最佳执行计划,但在某些场景下其生成的计划无法满足需求,此时用户可使用Hint指定特定执行计划。
- Hint应谨慎使用,建议在收集表统计信息、用
EXPLAIN
评估无Hint时优化器执行计划后再考虑使用。因为数据库条件变化和版本更新可能使Hint的适用性发生改变。
2、Hint及其特点
- 基于代价的优化器,与
Oracle
的Hint
类似。 - 如果使用
MySQL
的客户端执行带Hint的SQL语句,需要使用-c
选项登陆, 否则MySQL
客户端会将Hint
作为注释从用户SQL中去除,导致系统无法收到用户Hint
。 - 如果
server
端不认识SQL语句中的Hint
,直接忽略而不报错。 Hint
只影响数据库优化器生成计划的逻辑,而不影响SQL语句本身的语义。
3、Hint的使用
一条语句只能包含一个Hint注释,且该注释需紧跟SELECT
、UPDATE
、INSERT
、REPLACE
或DELETE
关键字。
Hint在语句注释中的语法格式如下:
{DELETE|INSERT|SELECT|UPDATE|REPLACE} /*+ hint_text [,hint_text...] */
从语法上看,Hint是一种特殊的SQL注释,所不同的是在注释的左标记后增加了一个加号(+
)。
使用Hint时需要注意以下规则:
- 加号(
+
)会让数据库将注释内容作为Hint列表处理,加号必须紧跟在注释起始符后,中间不能有空格,且注释内不能有换行。 - 多个hint可写在同一个注释中,用逗号分隔,例如
/*+ FUNC1, FUNC2(param) */
。 - Hint 包含拼写错误或语法错误时会被忽略。但是,数据库会考虑在同一注释中使用其他正确指定的 Hint。
SELECT
等语句的hint必须近接在关键字SELECT
之后,其他词之前。如:SELECT /*+ FUNC */ …
- Hint 的组合相互冲突时 Hint 无效。但是,数据库会在同一注释中考虑使用其他不冲突的 Hint。
4、Hint示例
Hint类型 | Hint名字 | Hint示例 | 备注 |
---|---|---|---|
与访问路径相关的Hint | INDEX Hint | /*+ INDEX(表名 索引名)*/ | - |
与访问路径相关的Hint | FULL Hint | /*+ FULL(e) */ | e为表的别名 |
与连接顺序相关的Hint | LEADING Hint | /*+ LEADING(a b) */ | a作为驱动表,带动b表进行连接 |
与连接操作相关的Hint | USE_MERGE Hint | /*+ USE_MERGE(a b) */ | 对a和b表之间的连接操作采用Sort - Merge Join算法,并将这两个表作为连接的左右表(内表或外表) |
与连接操作相关的Hint | USE_HASH Hint | /*+ USE_HASH(a b) */ | 对a和b表之间的连接操作采用Hash Join算法,并将这两个表作为连接的左右表(内表或外表) |
与连接操作相关的Hint | USE_NL Hint | USE_NL(a b) | 对a和b表之间的连接操作采用Nested Loop Join算法,并将这两个表作为连接的左右表(内表或外表) |
与连接操作相关的Hint | USE_BNL Hint | /*+ USE_BNL(a b) */ | 对a和b表之间的连接操作采用块嵌套循环连接算法,并将这两个表作为连接的左右表(内表或外表) |
与并行执行相关的Hint | PARALLEL Hint | /*+ PARALLEL(n) */ | - |
服务器端执行语句超时相关 | /*+query_timeout(100000000)*/ 单位:微秒 | /*+query_timeout(100000000)*/ 单位:微秒 | - |
强制读一致性相关 | /*+READ_CONSISTENCY(STRONG)*/ /*+READ_CONSISTENCY(WEAK)*/ | /*+READ_CONSISTENCY(STRONG)*/ /*+READ_CONSISTENCY(WEAK)*/ | - |
想获取更多实用干货,关注微信公众号【雅俗数据库】。