1.使用测试用户tester连接实验GaussDB实例。
sql
gsql -d testdb -h 192.168.3.60 -U tester -p 8000 -W Gauss@123 -r
2.创建测试表及索引。
sql
create table hint_t1(a int, b int, c int);
create index on hint_t1(a);
3.插入测试数据。
sql
insert into hint_t1 select generate_series(1,100000),generate_series(1, 100000),generate_series(1, 100000);
4.执行如下命令收集hint_t1表统计信息。
sql
analyze hint_t1;
5.执行SQL语句。
sql
testdb=> explain analyze select /*+ rows(hint_t1 -90000)*/ a from hint_t1 where hint_t1.a>999;
id | operation | A-time | A-rows | E-rows | Peak Memory | A-width | E-width | E-costs
----+-------------------------+--------+--------+--------+-------------+---------+---------+------------------
1 | -> Seq Scan on hint_t1 | 52.324 | 99001 | 9026 | 63KB | | 4 | 16.339..1631.000
(1 row)
Predicate Information (identified by plan id)
-----------------------------------------------
1 --Seq Scan on hint_t1
Filter: (a > 999)
Rows Removed by Filter: 999
(3 rows)
====== Query Summary =====
----------------------------------------
Datanode executor start time: 0.044 ms
Datanode executor run time: 65.920 ms
Datanode executor end time: 0.027 ms
Planner runtime: 0.545 ms
Query Id: 1948932738745690863
Total runtime: 66.005 ms
(6 rows)
从上述执行计划可以看到,查询时使用的是Seq scan全表扫描,耗时比较长。因为hint_t1表存在a列的索引,可以考虑使用IndexOnlyScan的方式进行优化。
6.执行SQL查询语句。
sql
select a from hint_t1 where hint_t1.a>999;
7.使用管理员用户root连接实验GaussDB实例。
sql
gsql -d testdb -p 8000 -r
8.查询视图dbe_perf.summary_statement获取unique_sql_id。
sql
testdb=# select unique_sql_id,query from dbe_perf.summary_statement where query like 'select%hint_t1%';
unique_sql_id | query
---------------+------------------------------------------
3752218171 | select a from hint_t1 where hint_t1.a>?;
(1 row)
9.创建调优SQL PATCH,使该SQL语句走IndexOnlyScan。
sql
testdb=# select * from dbe_sql_util.create_hint_sql_patch('patch1',3752218171,'IndexOnlyScan(hint_t1)');
create_hint_sql_patch
-----------------------
t
(1 row)
其中unique_sql_id使用之前步骤查询到的id。
10.使用测试用户tester连接实验GaussDB实例。
sql
gsql -d testdb -h 192.168.3.60 -U tester -p 8000 -W Gauss@123 -r
11.再次执行语句,查看执行计划。
sql
[Ruby@gs01 ~]$ gsql -d testdb -h 192.168.3.60 -U tester -p 8000 -W Gauss@123 -r
gsql ((GaussDB Kernel 505.2.1.SPC0800 build 85996fbb) compiled at 2025-07-03 01:15:58 commit 10558 last mr 24271 release)
SSL connection (cipher: ECDHE-RSA-AES128-GCM-SHA256, bits: 128)
Type "help" for help.
testdb=> explain analyze select /*+ rows(hint_t1 -90000)*/ a from hint_t1 where hint_t1.a>999;
NOTICE: Plan influenced by SQL hint patch
id | operation | A-time | A-rows | E-rows | Peak Memory | A-width | E-width | E-costs
----+----------------------------------------------------+--------+--------+--------+-------------+---------+---------+-----------------
1 | -> Index Only Scan using hint_t1_a_idx on hint_t1 | 32.733 | 99001 | 99026 | 93KB | | 4 | 0.000..2155.605
(1 row)
Predicate Information (identified by plan id)
------------------------------------------------------
1 --Index Only Scan using hint_t1_a_idx on hint_t1
Index Cond: (a > 999)
(2 rows)
====== Query Summary =====
----------------------------------------
Datanode executor start time: 0.037 ms
Datanode executor run time: 44.278 ms
Datanode executor end time: 0.019 ms
Planner runtime: 0.545 ms
Query Id: 1948932738745700674
Total runtime: 44.374 ms
(6 rows)
====== Query Others =====
---------------------------
Bypass: Yes
(1 row)
可以看到已经使用了SQL PATCH,扫描时使用的Index Only Scan,执行时间从66ms降到了44ms。
在实际业务场景中,如果客户应用侧不方便修改SQL代码,可以考虑使用SQL PATCH的方式来改变SQL语句的执行计划。
12.执行如下命令删除测试表。
sql
drop table hint_t1;
13.使用管理员用户root连接实验GaussDB实例。
sql
gsql -d testdb -p 8000 -r
14.执行如下命令删除SQL PATCH。
sql
[Ruby@gs01 ~]$ gsql -d testdb -p 8000 -r
gsql ((GaussDB Kernel 505.2.1.SPC0800 build 85996fbb) compiled at 2025-07-03 01:15:58 commit 10558 last mr 24271 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
testdb=# select * from dbe_sql_util.drop_sql_patch('patch1');
drop_sql_patch
----------------
t
(1 row)