本文介绍在 OceanBase 数据库关于 HINT 的使用规范。
HINT 应该少用,仅在收集了相关表的统计信息并且使用语句在没有 HINT 的情况下评估了优化器计划之后,才谨慎考虑使用。更改数据库条件以及在后续版本中增强查询性能可能会导致代码中的HINT 对性能产生重大影响。
HINT 介绍
-
基于代价的优化器,与 Oracle 的 HINT 类似。
-
如果 server 端不认识 SQL 语句中的 HINT,直接忽略而不报错。
-
HINT 只影响数据库优化器生成计划的逻辑,而不影响 SQL 语句本身的语义。
-
HINT 是一种机制,通过HINT可以使优化器生成某种特定的计划。 一般情况下,优化器会为用户查询选择最佳的执行计划,不需要用户使用 HINT 指定,但在某些场景下,优化器生成的执行计划可能不满足用户的要求,这时就需要用户使用 HINT 来显式指定生成某种执行计划。
HINT 语法
{DELETE|INSERT|SELECT|UPDATE|REPLACE} /*+ [HINT_text][hin_text]... */
-
一个语句块只能有一个注释包含 HINT,并且该注释必须跟随 SELECT、UPDATE、INSERT、MERGE 或 DELETE 关键字。
-
HINT 从语法上看是一种特殊的 SQL 注释, 所不同的是在注释的左标记后(
'/*' 符号)增加了一个
'+'。 既然是注释,如果 Server 端无法识别 SQL 语句中的 HINT,优化器会选择忽略用户 HINT 而使用默认的计划生成逻辑。另外,需要指明,HINT 只影响优化器生成计划的逻辑,而不影响 SQL 语句的语义。
-
定义 HINT 时需要注意的一些规则:
-
加号
'+' 使数据库将注释解释为 HINT 列表。加号必须紧跟在注释左标记符后,不允许有空格。
-
加号
'+' 和 HINT 文本之间的空格是可选的。如果注释中包含多个 HINT,则 HINT 间至少用一个空格或者用逗号进行分隔。
-
包含拼写错误或语法错误时会被忽略。但是,数据库会考虑在同一注释中其他正确指定的 HINT。
-
不跟随 DELETE、INSERT、MERGE、SELECT 或 UPDATE 关键字的 HINT 无效。
-
OceanBase 与 Oracle 除了在 HINT 理念不一致外,其他还有:
- Oracle leading HINT,出现不存在的表时候,HINT 是否生效会做推算,导致行为不确定,部分情况有效,部分情况全部无效。
HINT 使用示范
-
不带参数的,如
/*+ KAKA */。
-
带参数的,如
/*+ HAHA(param) */。
-
多个 HINT 可以写到同一个注释中,用逗号或者至少一个空格分隔,如
/*+ KAKA, HAHA(param)*/。
-
SELECT 语句的 HINT必须近接在关键字 SELECT 之后,其他词之前。如:
SELECT /*+ KAKA */。
-
UPDATE,DELETE语句的 HINT 必须紧接在关键字 UPDATE,DELETE 之后。如:
UPDATE /*+ KAKA */ ,
DELETE /*+ KAKA */。
常用 HINT 类型
|
Hint 名称 |
Hint 参数 |
Hint 语义 |
| NO_REWRITE |
|
不改写 SQL。 |
| READ_CONSISTENCY |
weak|strong|frozen |
weak:弱一致性读 strong:强一致性读 frozen:读最近一次冻结点的数据 |
| INDEX_HINT |
[ qb_name ] table_nameindex_name |
指定查询表时选择的索引。 |
| QUERY_TIMEOUT |
int64 |
指定语句执行的超时时间,单位是微秒(us)。 |
| LEADING |
[ qb_name ] table_name [, table_name ] |
指定多表连接时的顺序。 |
| ORDERED |
|
指定多表连接顺序按 SQL 中表出现的顺序。 |
| FULL |
[qb_name] table_name |
指定表的访问方式为全表扫描(有主键时会读主键)。 |
| USE_MERGE |
[qb_name] table_name [,table_name] |
指定多表连接时使用 MERGE 算法。 |
| USE_NL |
[ qb_name ] table_name [, table_name] |
指定多表连接时使用 NEST LOOP算法。 |
| USE_BNL |
[qb_name] table_name [,table_name] |
指定多表连接时适用 BLOCK NEST LOOP 算法。 |
| USE_HASH_AGGREGATION |
[ qb_name] |
指定 aggregate 方法使用 HASH AGGREGATE,例如 HASH GROUP BY,HASH DISTINCT。 |
| NO_USE_HASH_AGGREGATION |
[ qb_name ] |
指定 aggregate 方法不使用HASH AGGREGATE,使用MERGE GROUP BY,MERGE DISTINCT 。 |
| QB_NAME |
[ qb_name] |
指定 query block 的名称。 |
| PARALLEL |
int64 |
指定分布式执行的并行度。 |
更多 hint 相关内容请参考
《性能调优》 中的
SQL 调优指南 。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70026124/viewspace-2932851/
,如需转载,请注明出处,否则将追究法律责任。