Hint报告¶
Hint引导优化器生成用户期望的计划,但优化器不会因为某些Hint(如语法错误、冲突等)未使用而给处提示信息,所以用户没有办法了解指定的Hint是否被真正的使用,为了让用户能更清晰的了解Hint使用情况,数据库引入了Hint报告功能。
该报告主要展示了Hint的使用情况,对于未使用的Hint,给出了具体原因。
使用该功能需要打开参数ENABLE_HINT_REPORT,下面介绍Hint报告的用法。
用法¶
- 创建环境
create table t1(a int);
create table t2(a int);
- 开启ENABLE_HINT_REPORT参数,默认参数为关闭状态。
set ENABLE_HINT_REPORT=true;
- 使用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报告中展示了如下信息:
- 用户指定Hint的总数量为5个,其中两个为语法错误,两个为冲突
- 列出了未被优化器使用的Hint的及其原因,如 abc 是因为语法错误导致未被使用
- 列出了被优化器使用的Hint,如 use_nl(t1,t2)
至此对如何解读Hint报告有了一个初步的认识,下面详细介绍一下报告的格式以及使用示例
格式¶
[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,该参数默认关闭
示例¶
- 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
- Hint参数错误
- 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语法 中查看
- 表名不存在
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
注解
有别名应该使用别名,否则会报找不到表名错误
- 索引不存在
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
- 视图合并导致视图名失效
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
- 参数重复错误
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
- 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)
- 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)