Hint报告

Hint引导优化器生成用户期望的计划,但优化器不会因为某些Hint(如语法错误、冲突等)未使用而给处提示信息,所以用户没有办法了解指定的Hint是否被真正的使用,为了让用户能更清晰的了解Hint使用情况,数据库引入了Hint报告功能。

该报告主要展示了Hint的使用情况,对于未使用的Hint,给出了具体原因。

使用该功能需要打开参数ENABLE_HINT_REPORT,下面介绍Hint报告的用法。

用法

  1. 创建环境
create table t1(a int);
create table t2(a int);
  1. 开启ENABLE_HINT_REPORT参数,默认参数为关闭状态。
set ENABLE_HINT_REPORT=true;
  1. 使用explain命令执行含有hint的SQL语句,具体细节查看 explain
explain select /*+ full(t1) index(t1) use_nl(t1,t2) abc() */ * from t1,(select /*+ abc() */ * from t2) where t1.a = 1;

                                QUERY PLAN
----------------------------------------------------------------------
Nested Loop(Inner Join)  (cost=0.00..192.81 rows=41 width=16)
->  Seq Scan on T1  (cost=0.00..110.40 rows=41 width=4)
        Scan Key: (A = 1)
->  Seq Scan on T2  (cost=0.00..2.00 rows=1 width=12)


Hint Report
-----------
Total hint num: 5 (S - SYNTAX(2),C - CONFLICT(2))

GROUP:0
        - ERROR
            S - abc / syntax error at or near "ABC" at character 52
            C - full(t1) / Hint conflicts with index(t1)
            C - index(t1) / Hint conflicts with full(t1)

        - ENABLE
            use_nl(t1,t2)


GROUP:1
        - ERROR
            S - abc / syntax error at or near "ABC" at character 83



(26 rows)

可以看到,结果包含了两部分的内容:执行计划和Hint报告。

执行计划这里不做介绍,详情参见 执行计划

Hint报告中展示了如下信息:

  1. 用户指定Hint的总数量为5个,其中两个为语法错误,两个为冲突
  2. 列出了未被优化器使用的Hint的及其原因,如 abc 是因为语法错误导致未被使用
  3. 列出了被优化器使用的Hint,如 use_nl(t1,t2)

至此对如何解读Hint报告有了一个初步的认识,下面详细介绍一下报告的格式以及使用示例

格式

../../../../_images/hint_report.png

[1] Total hint num: 5 整个sql中Hint的总个数

[2] S - SYNTAX(2) Hint忽略状态和其简写,括号中是此类状态Hint的个数

Hint报告定义的忽略状态有以下几类

  • SYNTAX(S): Hint语法错误
  • PARAMETER(P): Hint参数错误
  • UNUSED(U): Hint无效
  • CONFLICT(C): Hint间冲突

[3] GROUP 表示Hint组

[4] ERROR & ENABLE 每组Hint分为两块展示,Error为忽略Hint块,Enable为应用Hint块

[5] S - abc / syntax error at or near "ABC" at character 52 Hint忽略状态简写 - Hint串 / 忽略原因

注解

Group顺序 与 Select顺序没有关系,只是用来记录哪些Hint在一个 /*+ */ 中。

Hint被忽略的常见情况见 Hint忽略情况

如果想打印Hint报告,请设置ENABLE_HINT_REPORT,该参数默认关闭

示例

  1. Hint语法错误
--错误的Hint关键字
explain select /*+ abc((( */ * from t1;
                              QUERY PLAN
----------------------------------------------------------------------
 Seq Scan on T1  (cost=0.00..89.92 rows=8192 width=4)


 Hint Report
 -----------
 Total hint num: 1 (S - SYNTAX(1))

 GROUP:0
         - ERROR
             S - abc / syntax error at or near "ABC" at character 19


--错误的Hint格式
explain select /*+ full((( */ * from t1;
                              QUERY PLAN
----------------------------------------------------------------------
 Seq Scan on T1  (cost=0.00..89.92 rows=8192 width=4)


 Hint Report
 -----------
 Total hint num: 1 (S - SYNTAX(1))

 GROUP:0
         - ERROR
             S - full(( / syntax error at or near "(" at character 25
  1. Hint参数错误
  1. Hint参数个数存在错误
explain select /*+ full(t1,t1) */ * from t1;
                               QUERY PLAN
------------------------------------------------------------------------
 Seq Scan on T1  (cost=0.00..89.92 rows=8192 width=4)


 Hint Report
 -----------
 Total hint num: 1 (P - PARAMETER(1))

 GROUP:0
         - ERROR
             P - full(t1,t1) / The number of parameters does not match

注解

Hint语法以及参数个数可以在 Hint语法 中查看

  1. 表名不存在
explain select /*+ full(t2) */ * from t1;
                      QUERY PLAN
------------------------------------------------------
 Seq Scan on T1  (cost=0.00..89.92 rows=8192 width=4)


 Hint Report
 -----------
 Total hint num: 1 (P - PARAMETER(1))

 GROUP:0
         - ERROR
             P - full(t2) / Table "T2" not found


explain select /*+ full(t1) */ * from t1 t2;
                        QUERY PLAN
----------------------------------------------------------
 Seq Scan on T1 T2  (cost=0.00..89.92 rows=8192 width=4)


 Hint Report
 -----------
 Total hint num: 1 (P - PARAMETER(1))

 GROUP:0
         - ERROR
             P - full(t1) / Table "T1" not found

注解

有别名应该使用别名,否则会报找不到表名错误

  1. 索引不存在
explain select /*+ index(t1 idx2) */ * from t1;
                        QUERY PLAN
----------------------------------------------------------
 Seq Scan on T1  (cost=0.00..89.92 rows=8192 width=4)


 Hint Report
 -----------
 Total hint num: 1 (P - PARAMETER(1))

 GROUP:0
         - ERROR
             P - index(t1 idx2) / Index "IDX2" not found
  1. 视图合并导致视图名失效
explain select /*+ full(tt1) */ * from (select * from t1) tt1;
                       QUERY PLAN
--------------------------------------------------------
 Seq Scan on T1  (cost=0.00..89.92 rows=8192 width=4)


 Hint Report
 -----------
 Total hint num: 1 (P - PARAMETER(1))

 GROUP:0
         - ERROR
             P - full(tt1) / View pullup "TT1" invalid
  1. 参数重复错误
explain select /*+ index(t1 idx1 idx1) */ * from t1;
                                     QUERY PLAN
------------------------------------------------------------------------------------
 Index Scan using IDX1(Fast Index Scan) on T1  (cost=0.00..82.92 rows=8192 width=4)


 Hint Report
 -----------
 Total hint num: 1 (P - PARAMETER(1))

 GROUP:0
         - ERROR
             P - index(t1 idx1 idx1) / Duplicate parameter
  1. Hint无效

Hint本身没有错误,但是不能生成这种路径,例如没有连接条件,但是使用mergejoin连接

explain select /*+ use_mj(t1,t2) */ * from t1,t2;
                                        QUERY PLAN
------------------------------------------------------------------------------------------
 Nested Loop(Inner Join)  (cost=100000000.00..100000166.84 rows=8192 width=16)
   ->  Seq Scan on T2  (cost=0.00..2.00 rows=1 width=12)
   ->  Index Scan using IDX1(Fast Index Scan) on T1  (cost=0.00..82.92 rows=8192 width=4)


 Hint Report
 -----------
 Total hint num: 1 (U - UNUSED(1))

 GROUP:0
         - ERROR
             U - use_mj(t1,t2)
  1. Hint之间发生冲突

如果Hint和当前组中的任意Hint存在冲突,则Hint失效

explain select /*+ use_mj(t1,t2) use_hj(t1,t2) use_nl(t1,t2) */ * from t1,t2;
                                        QUERY PLAN
------------------------------------------------------------------------------------------
 Nested Loop(Inner Join)  (cost=0.00..166.84 rows=8192 width=16)
   ->  Seq Scan on T2  (cost=0.00..2.00 rows=1 width=12)
   ->  Index Scan using IDX1(Fast Index Scan) on T1  (cost=0.00..82.92 rows=8192 width=4)


 Hint Report
 -----------
 Total hint num: 3 (C - CONFLICT(3))

 GROUP:0
         - ERROR
             C - use_mj(t1,t2) / Hint conflicts with use_hj(t1,t2)
             C - use_hj(t1,t2) / Hint conflicts with use_mj(t1,t2)
             C - use_nl(t1,t2) / Hint conflicts with use_mj(t1,t2)