金仓数据库 KingbaseES Hint 的使用

55 阅读3分钟

关键字:

Hint

HINT概述

KingbaseES使用的是基于成本的优化器。优化器会估计SQL语句的每个可能的执行计划的成本,然后选择成本最低的执行计划来执行。因为优化器不计算数据的某些属性,比如列之间的相关性,优化器有时选择的计划并不一定是最优的。

Hint的作用就是通过使用特殊形式的注释中的hint短语来指定执行SQL语句所用的执行计划。Hint为用户提供了直接影响执行计划生成的手段,用户可以通过指定join顺序,join、scan方法,指定结果行数等多个手段来进行执行计划的调优,以提升查询的性能。

Hint功能

hint的使用

HINT通过在目标SQL语句SELECT/UPDATE/DELETE/INSERT/MERGE之后给出的特殊形式的注释来读取HINT注释。注释的形式以字符序列‘/*+’开头以‘*/’结尾,例如/*+SeqScan(tablename)*/,其具体使用方法如下:

  1. 在kingbase.conf配置文件中,配置: enable_hint = on .
  2. 启动数据库
  3. 使用Hint的注释使Hint生效:

4. 配置参数

参数

描述

默认值

enable_hint

启用hint

Off

hint_debug_print

是否打印HINT的debug信息

Off

hint_message_level

指定debug打印的信息级别。可用的值为error, warning, notice, info, log, debug1, debug2, debug3, debug4,debug5

Log

参数enable_hint默认关闭,当此参数关闭后,SQL查询语句中的HINT注释将不会对执行计划产生影响。

当参数hint_debug_print设置为on,并且hint_message_level设置为log后,在一个带有格式正确的HINT注释的SQL语句运行时,会一同输出hint的调试信息,内容包含used hint、not used hint、duplication hint、error hint。

5. 使用示例

测试用例:

create table t1(id int, val int, name varchar(64));

create table t2(id int, val int);

create table t3(id int, val int);

create table t4(id int, val int);

create table t5(id int, val int);

create index t1_idx on t1(id);

create index t2_idx on t2(id);

create index t3_idx on t3(id);

create index t4_idx on t4(id);

insert into t1 select i, i%5000, 'Kingbase'||(i%5) from generate_series(1,3000000) as x(i);

insert into t2 select i, i%5000 from generate_series(1,1000000) as x(i);

insert into t3 select i, i%5 from generate_series(1,100) as x(i);

insert into t4 select i%5, i%5 from generate_series(1,100) as x(i);

insert into t5 select i, i%5 from generate_series(1,100) as x(i);

analyze t1;

analyze t2;

analyze t3;

create table pt(col1 INT, col2 INT) PARTITION BY RANGE (col1);

create table pt_1 partition of pt for values from (0) to (10);

create table pt_2 partition of pt for values from (10) to (20);

create index pt_col2_idx on pt(col2);

create unique index pt_col2_idx_global on pt(col2) global;

为防止并行影响测试结果,以下所有示例结果是在关闭并行扫描的前提下进行

set max_parallel_workers_per_gather = 0;

SeqScan HINT例子:

explain select * from t1 where id=20;

QUERY PLAN

------------------------------------------------------------------

-> Index Scan using t1_idx on t1 (cost=0.43..8.45 rows=1 width=18)

Index Cond: (id = 20)

(2 rows)

explain select/*+seqscan(t1)*/ * from t1 where id=20;

QUERY PLAN

------------------------------------------------------------------

-> Seq Scan on t1 (cost=0.00..56731.00 rows=1 width=18)

Filter: (id = 20)

(2 rows)

IndexScan HINT例子:

explain select * from t1 where id > 10 and id < 20000000;

QUERY PLAN

------------------------------------------------------------------

-> Seq Scan on t1 (cost=0.00..64231.00 rows=2999990 width=18)

Filter: ((id > 10) AND (id < 20000000))

(2 rows)

explain select/*+IndexScan(t1)*/ * from t1 where id > 10 and id < 20000000;

QUERY PLAN

------------------------------------------------------------------

-> Index Scan using t1_idx on t1 (cost=0.43..112326.23 rows=2999990 width=18

Index Cond: ((id > 10) AND (id < 20000000))

(2 rows)

explain select * from pt where col2 < 10;

QUERY PLAN

------------------------------------------------------------------------------------

Append (cost=9.99..66.34 rows=1506 width=8)

-> Bitmap Heap Scan on pt_1 (cost=9.99..29.40 rows=753 width=8)

Recheck Cond: (col2 < 10)

-> Bitmap Index Scan on pt_1_col2_idx (cost=0.00..9.80 rows=753 width=0)

Index Cond: (col2 < 10)

-> Bitmap Heap Scan on pt_2 (cost=9.99..29.40 rows=753 width=8)

Recheck Cond: (col2 < 10)

-> Bitmap Index Scan on pt_2_col2_idx (cost=0.00..9.80 rows=753 width=0)

Index Cond: (col2 < 10)

explain select/*+indexscan(pt pt_col2_idx_global)*/ * from pt where col2 < 10;

QUERY PLAN

----------------------------------------------------------------------------------------

Global Index Scan using pt_col2_idx_global on pt (cost=0.12..13.15 rows=1506 width=8)

Index Cond: (col2 < 10)

(2 行记录)