实验二十八 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)
相关推荐
剩下了什么11 小时前
MySQL JSON_SET() 函数
数据库·mysql·json
山峰哥11 小时前
数据库工程与SQL调优——从索引策略到查询优化的深度实践
数据库·sql·性能优化·编辑器
较劲男子汉11 小时前
CANN Runtime零拷贝传输技术源码实战 彻底打通Host与Device的数据传输壁垒
运维·服务器·数据库·cann
java搬砖工-苤-初心不变11 小时前
MySQL 主从复制配置完全指南:从原理到实践
数据库·mysql
山岚的运维笔记13 小时前
SQL Server笔记 -- 第18章:Views
数据库·笔记·sql·microsoft·sqlserver
roman_日积跬步-终至千里14 小时前
【LangGraph4j】LangGraph4j 核心概念与图编排原理
java·服务器·数据库
汇智信科14 小时前
打破信息孤岛,重构企业效率:汇智信科企业信息系统一体化运营平台
数据库·重构
野犬寒鸦14 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
WHD30615 小时前
苏州数据库(SQL Oracle)文件损坏修复
hadoop·sql·sqlite·flume·memcached
晚霞的不甘16 小时前
揭秘 CANN 内存管理:如何让大模型在小设备上“轻装上阵”?
前端·数据库·经验分享·flutter·3d