实验二十八 SQL PATCH调优

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)
相关推荐
I***t7161 小时前
一条sql 在MySQL中是如何执行的
数据库·sql·mysql
一 乐1 小时前
应急知识学习|基于springboot+vue的应急知识学习系统(源码+数据库+文档)
数据库·vue.js·spring boot
微学AI2 小时前
内网穿透的应用-突破局域网束缚,MongoDB 远程访问使用cpolar原来可以这么简单
数据库·mongodb
大锦终4 小时前
【MySQL】内置函数
数据库·mysql
猿小喵4 小时前
索引优化-MySQL性能优化
数据库·mysql·性能优化
n***F8755 小时前
修改表字段属性,SQL总结
java·数据库·sql
q***78377 小时前
mysql表添加索引
数据库·mysql
翔云1234567 小时前
MySQL 机器重启后,gtid_executed 是如何初始化的
数据库·mysql·adb