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;