openGauss学习笔记-272 openGauss性能调优-实际调优案例01-调整查询重写GUC参数rewrite_rule

ops/2024/10/18 14:21:51/

文章目录

    • openGauss学习笔记-272 openGauss性能调优-实际调优案例01-调整查询重写GUC参数rewrite_rule
      • 272.1 目标列子查询提升参数intargetlist
      • 272.2 提升无agg的子查询uniquecheck

openGauss272_openGauss01GUCrewrite_rule_1">openGauss学习笔记-272 openGauss性能调优-实际调优案例01-调整查询重写GUC参数rewrite_rule

rewrite_rule包含了多个查询重写规则:magicset、partialpush、uniquecheck、disablerep、intargetlist、predpush。下面简要说明一下其中重要的几个规则的使用场景:

272.1 目标列子查询提升参数intargetlist

通过将目标列中子查询提升,转为JOIN,往往可以极大提升查询性能。举例如下查询:

openGauss=#  set rewrite_rule='none';
SET
openGauss=# create table t1(c1 int,c2 int);
CREATE TABLE
openGauss=# create table t2(c1 int,c2 int);
CREATE TABLE
openGauss=#  explain (verbose on, costs off) select c1,(select avg(c2) from t2 where t2.c2=t1.c2) from t1 where t1.c1<100 order by t1.c2;QUERY PLAN
-----------------------------------------------SortOutput: t1.c1, ((SubPlan 1)), t1.c2Sort Key: t1.c2->  Seq Scan on public.t1Output: t1.c1, (SubPlan 1), t1.c2Filter: (t1.c1 < 100)SubPlan 1->  AggregateOutput: avg(t2.c2)->  Seq Scan on public.t2Output: t2.c1, t2.c2Filter: (t2.c2 = t1.c2)
(12 rows)

由于目标列中的相关子查询(select avg(c2) from t2 where t2.c2=t1.c2)无法提升的缘故,导致每扫描t1的一行数据,就会触发子查询的一次执行,效率低下。如果打开intargetlist参数会把子查询提升转为JOIN,来提升查询的性能:

openGauss=#  set rewrite_rule='intargetlist';
SET
openGauss=# explain (verbose on, costs off) select c1,(select avg(c2) from t2 where t2.c2=t1.c2) from t1 where t1.c1<100 order by t1.c2;QUERY PLAN
-----------------------------------------------SortOutput: t1.c1, (avg(t2.c2)), t1.c2Sort Key: t1.c2->  Hash Left JoinOutput: t1.c1, (avg(t2.c2)), t1.c2Hash Cond: (t1.c2 = t2.c2)->  Seq Scan on public.t1Output: t1.c1, t1.c2Filter: (t1.c1 < 100)->  HashOutput: (avg(t2.c2)), t2.c2->  HashAggregateOutput: avg(t2.c2), t2.c2Group By Key: t2.c2->  Seq Scan on public.t2Output: t2.c2
(16 rows)

272.2 提升无agg的子查询uniquecheck

子链接提升需要保证对于每个条件只有一行输出,对于有agg的子查询可以自动提升,对于无agg的子查询如:

select t1.c1 from t1 where t1.c1 = (select t2.c1 from t2 where t1.c1=t2.c2) ;

重写为:

select t1.c1 from t1 join (select t2.c1 from t2 where t2.c1 is not null group by t2.c1(unique check)) tt(c1) on tt.c1=t1.c1;

为了保证语义等价,子查询tt必须保证对于每个group by t2.c1只能有一行输出。打开uniquecheck查询重写参数保证可以提升并且等价,如果在运行时输出了多于一行的数据,就会报错。

openGauss=# set rewrite_rule='uniquecheck';
SET
openGauss=#  explain verbose select t1.c1 from t1 where t1.c1 = (select t2.c1 from t2 where t1.c1=t2.c1);QUERY PLAN
-------------------------------------------------------------------------------------Hash Join  (cost=43.36..104.40 rows=2149 distinct=[200, 200] width=4)Output: t1.c1Hash Cond: (t1.c1 = subquery."?column?")->  Seq Scan on public.t1  (cost=0.00..31.49 rows=2149 width=4)Output: t1.c1, t1.c2->  Hash  (cost=40.86..40.86 rows=200 width=8)Output: subquery."?column?", subquery.c1->  Subquery Scan on subquery  (cost=36.86..40.86 rows=200 width=8)Output: subquery."?column?", subquery.c1->  HashAggregate  (cost=36.86..38.86 rows=200 width=4)Output: t2.c1, t2.c1Group By Key: t2.c1Filter: (t2.c1 IS NOT NULL)Unique Check Required->  Seq Scan on public.t2  (cost=0.00..31.49 rows=2149 width=4)Output: t2.c1
(16 rows)

注意:因为分组group by t2.c1 unique check发生在过滤条件tt.c1=t1.c1之前,可能导致原来不报错的查询重写之后报错。举例:

有t1,t2表,其中的数据为:

openGauss=#  select * from t1 order by c2;c1 | c2
----+----1 |  12 |  23 |  3
(3 rows)
openGauss=#  select * from t2 order by c2;c1 | c2
----+----1 |  12 |  23 |  34 |  44 |  45 |  5
(6 rows)

分别关闭和打开uniquecheck参数对比,打开之后报错。

openGauss=#  select t1.c1 from t1 where t1.c1 = (select t2.c1 from t2 where t1.c1=t2.c2) ;c1
----123
(3 rows)
openGauss=#  set rewrite_rule='uniquecheck';
SET
openGauss=#  select t1.c1 from t1 where t1.c1 = (select t2.c1 from t2 where t1.c1=t2.c2) ;
ERROR:  more than one row returned by a subquery used as an expression

👍 点赞,你的认可是我创作的动力!

⭐️ 收藏,你的青睐是我努力的方向!

✏️ 评论,你的意见是我进步的财富!

图片


http://www.ppmy.cn/ops/27379.html

相关文章

【PG-2】PostgreSQL存储管理器

2. PostgreSQL存储管理器 src/backend/storage (base) torrestorresの机革:~/codes/postgresql-16.2/src/backend/storage$ ls Makefile buffer file freespace ipc large_object lmgr meson.build objfiles.txt page smgr sync存储管理器—smgr 通用存储管理器 …

Ubuntu 根目录扩容

环境 物理机&#xff1a;MacBook Air M2 Sonoma 14.4.1 虚拟机&#xff1a;VMware Fusion Player 13.5.0 镜像&#xff1a;Jammy Desktop ARM64 步骤 删除所有快照&#xff0c;关闭镜像&#xff0c;在 vm 上找到该镜像的硬盘设置&#xff0c;进行扩容&#xff1b; 开启镜像&am…

【Qt之·路径获取】

系列文章目录 文章目录 前言一、使用相对路径1.1 相对路径1.2 绝对路径1.3 QDir类1.4 QFileDialog对话框 二、示例2.1 示例一 总结 前言 在进行Qt开发时&#xff0c;经常需要获取文件的路径&#xff0c;如图片、音频、配置文件等。路径的获取可以通过直接指定绝对路径或者使用相…

RuoYi-Vue-Plus (SPEL 表达式)

RuoYi-Vue-Plus 中SPEL使用 DataScopeType 枚举类中&#xff1a; /*** 部门数据权限*/DEPT("3", " #{#deptName} #{#user.deptId} ", " 1 0 "), PlusDataPermissionHandler 拦截器中定义了解析器&#xff1a; buildDataFilter 方法中根据注解的…

TCP/IP和HTTP协议

TCP/IP OSI 七层模型在提出时的出发点是基于标准化的考虑&#xff0c;而没有考虑到具体的市场需求&#xff0c;使得该模型结构复杂&#xff0c;部分功能冗余&#xff0c;因而完全实现 OSI 参考模型的系统不多。而 TCP/IP 参考模型直接面向市场需求&#xff0c;实现起来也比较…

【C语言】编译与链接

1.翻译环境与运行环境 在ANSI C的任何一种实现中&#xff0c;存在两个不同的环境。 1.翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令&#xff08;二进制指令&#xff09; 2.执行环境&#xff0c;它用于实际执行代码 2.翻译环境 那么翻译环境是怎么将源代码…

STM32 F103C8T6学习笔记17:类IIC通信—MLX90614红外非接触温度计

今日学习配置MLX90614红外非接触温度计 与 STM32 F103C8T6 单片机的通信 文章提供测试代码讲解、完整工程下载、测试效果图 本文需要用到的大概基础知识&#xff1a;1.3寸OLED配置通信显示、IIC通信、 定时器配置使用 这里就只贴出我的 OLED驱动方面的网址链接了&#xff1a…

Rust 命令行参数解析指南

0x00 前言 通过 Rust 的 Governance 可以看到 Rust 的通过三种方式管理社区&#xff1a; RFC processTeamsWorking Groups 在 Working Groups 中我发现竟然有一个叫 Command-line interfaces (CLI) working group 的工作组(简称 WG-CLI)。很明显&#xff0c;如果 Rust 对于 …