hint 是一种特殊的 SQL 注释,SQL注释的一般语法和C语言的注释语法相同,即/* … */。而hint的语法在此基础上加了一个加号,型如/*+ … */。既然是注释,那么如果Server端不认识你SQL语句中的hint,它可以直接忽略而不必报错。这样做的一个好处是,同一条SQL发给不同的数据库产品,不会因为hint引起语法错误。hint只影响数据库服务器端内部优化的逻辑,而不影响SQL语句本身的语义。
OceanBase支持的 hint 有以下几个特点:
不带参数的,如/*+ KAKA* /。
带参数的,如/*+ HAHA(param)* /。
多个hint可以写到同一个注释中,用逗号分隔,如/*+ KAKA, HAHA(param) */。
SELECT 语句的 hint 必须紧接在关键字SELECT之后,其他词之前。如:SELECT /*+ KAKA */ …。
UPDATE、DELETE语句的 hint 必须紧接在关键字 UPDATE、DELETE之后。
支持索引hint。
OceanBase 支持的 hint 如下表所示。
hint | 参数 | 适用语句 | 含义 |
READCONSISTENCY | WEAK,STRONG,FROZEN | SELECT | 表明是强一致性读还是弱一致性读,如果 SQL 语句中不指定,默认值根据系统变量ob_read_consistency 的值决定。FROZEN 表示读最近一次冻结点的数据,冻结版本号由系统自动选择。 |
FROZEN_VERSION | 冻结版本号 | SELECT | 只读指定版本的数据。 |
READ_ZONE | FOLLOWER或LEADER | SELECT | 限制请求发到指定集群。READ_ZONE(FOLLOWER)是尽量选备集群,不存在备集群也没关系。这个hint仅控制 OceanBase 客户端对 SQL 语句的路由策略,和 READ_CONSISTENCY 没有关联。 |
QUERY_TIMEOUT | 超时时间,单位微秒 | 所有DML语句 | 设定Server端执行语句的超时时间,超时以后Server端中断执行并返回超时错误码。 |
USE_NL | USE_NL(右物理表名) | SELECT | 使用NESTED LOOP JOIN对两表JOIN,要求至少有一个JOIN条件,可以没有非WHERE条件。参考Oracle用法。 |
USE_MERGE | 表名 | SELECT | Merge Join 是先将关联表的关联列各自做排序,然后从各自的排序表中抽取数据,到另一个排序表中做匹配,因为mergejoin需要做更多的排序,所以消耗的资源更多。 |
LEADING | 表名 | SELECT | 在一个多表关联的查询中,该Hint指定由哪个表作为驱动表,告诉优化器首先要访问哪个表上的数据。 |
ORDERED | SELECT | 该hint按照From后面的表的顺序来选择驱动表 | |
USE_PLAN_CACHE | DEFAULT/NONE | 所有DML语句 | 设置使用某种执行计划 |
INDEX | INDEX(表名索引名) | 所有DML语句 | 和Oracle类似,设定对于指定表的查询强制走索引名,如果索引不存在或者不可用,也不报错。例如SELECT /+ INDEX(t1 i1) , INDEX(t2 i2)/ from t1, t2 WHEREt1.c1=t2.c1; DELETE /+ INDEX(t1 i1) / from t1 WHERE t1.c1=1; |
PARALLEL | PARALLEL(N) | SELECT | 指定SQL的并发数,MS能并发的发起对不同tablet的请求。 只有满足以下条件之一的SELECT语句,才会并发 1. 包含聚合函数 2. 包含groupby 3. 包含order by 4. 不包含limit 例如select /+ parallel(5) / count() from t1; |
TOPK | TOPK(param1 param2) | SELECT | 获得近似值 对于某些大的OLAP查询来说,数据量比较大,查询的时间较长。在某种情况下,我们可以通过牺牲结果的精确性,来获得较好的查询时间的改进。 select /+ topk(90 1000) / sum(c2), c1 from t1 group by c1order by sum(c2) limit 10 topk是hint topk(a b) 注意中间没有逗号 a是整数,取值范围是[0, 100]。表示精度,100表示完全精确,90表示90%准确。精度越高,得到的结果越精确,但是相应的耗时也越长 b是正整数[0, 正无穷],这个数字和实现相关,含义下面会解释。近似算法只有在同时带有group by、order by、 limit的查询中才会生效。 |
LOG_LEVEL | l ERROR l USER_ERROR l WARN l INFO l TRACE l DEBUG | 所有DML语句 | 设置语句级的日志级别。(此功能只有DBA能操作。) 例如: select/+log_level(‘debug’)/ from t; select /+log_level(‘sql.:debug,common.:info’)/ * from t; |