PostgreSQL和openGauss优化器对一个关联查询的SQL优化改写

news/2024/10/18 16:54:36/

PostgreSQL和openGauss数据库优化器在merge join关联查询的SQL优化改写

    • PostgreSQL 查询计划
    • openGauss 查询计划
    • 拓展对比

看腻了文章就来听听视频讲解吧:https://www.bilibili.com/video/BV1oH4y137P7/

数据库类型数据库版本
PostgreSQL16.2
openGauss6.0

创建测试表和数据

drop table IF EXISTS t_test_1;
drop table IF EXISTS t_test_2;
create table t_test_1 (id int, info text);
insert into t_test_1 select generate_series(1,10000000),'testdb';
create table t_test_2 as select * from t_test_1;
create index idx_t_test_1_id on t_test_1(id);
create index idx_t_test_2_id on t_test_2(id);
vacuum analyze t_test_1;
vacuum analyze t_test_2;

查询SQL

-- Merge Join
explain (analyze,buffers) select count(*) from t_test_1 t1 join t_test_2 t2 on (t1.id=t2.id) where t1.id between 5000000 and 5700000;
-- 等价写法
explain (analyze,buffers) select count(*) from t_test_1 t1 join t_test_2 t2 on (t1.id=t2.id) where t1.id between 5000000 and 5700000 and t2.id between 5000000 and 5700000;

PostgreSQL 查询计划

测试 PostgreSQL 数据库版本为:16.2

-- 关闭并行,方便查看执行计划
set max_parallel_workers = 0;
set max_parallel_workers_per_gather = 0;

image.png

从执行计划实际扫描的行数「 rows 」,可以看到 MergeJoin 会从索引开头全部扫描,直到超过匹配范围,即 t1 表根据where条件的between过滤走的索引扫描获取数据,t2 表从索引开头全部扫描到匹配范围。

openGauss__41">openGauss 查询计划

测试 openGauss 数据库版本为:6.0

image.png
相比 PostgreSQL 的优化器,openGauss在这种场景的处理上相对智能点

拓展对比

PostgreSQL数据库调整where过滤条件行数后的执行计划:

-- Hash Join
explain (analyze,buffers) select count(*) from t_test_1 t1 join t_test_2 t2 on (t1.id=t2.id) where t1.id between 5000000 and 5500000;
-- 等价改写
explain (analyze,buffers) select count(*) from t_test_1 t1 join t_test_2 t2 on (t1.id=t2.id) where t1.id between 5000000 and 5500000 and t2.id between 5000000 and 5500000;

image.png

-- Nested Loop
explain (analyze,buffers) select count(*) from t_test_1 t1 join t_test_2 t2 on (t1.id=t2.id) where t1.id between 5000000 and 5200000;
-- 等价改写
explain (analyze,buffers) select count(*) from t_test_1 t1 join t_test_2 t2 on (t1.id=t2.id) where t1.id between 5000000 and 5200000 and t2.id between 5000000 and 5200000;

image.png

openGauss数据库调整where过滤条件行数后的执行计划:

-- PG Hash Join
explain (analyze,buffers) select count(*) from t_test_1 t1 join t_test_2 t2 on (t1.id=t2.id) where t1.id between 5000000 and 5500000;
-- PG Nested Loop
explain (analyze,buffers) select count(*) from t_test_1 t1 join t_test_2 t2 on (t1.id=t2.id) where t1.id between 5000000 and 5200000;

image.png

随着where条件过滤数量的变化,PostgreSQL执行计划选择的方式会跟着有所变化,openGauss都是选择merge join的执行计划,按照merge join针对数据有序的场景到也算是正常


http://www.ppmy.cn/news/1458322.html

相关文章

《Linux运维总结:ARM64架构CPU基于docker-compose一离线部署rabbitmq 3.10.25容器版镜像模式集群工具》

总结:整理不易,如果对你有帮助,可否点赞关注一下? 更多详细内容请参考:《Linux运维篇:Linux系统运维指南》 一、部署背景 由于业务系统的特殊性,我们需要面向不通的客户安装我们的业务系统&…

59岁前TVB男拳王内地登台疑黑面 被批耍大牌

现年59岁的郭政鸿在2015年离巢TVB后转往内地发展,密密拍剧、登台及直播带货,短短几年就已经储够钱,斥资过千万买楼,成功上车做业主,可见收入丰厚。 早前郭政鸿现身顺德,在酒吧登台唱歌,有网民上…

57. 【Android教程】相机:Camera

相机现在已经不仅仅是手机必备神器了,甚至相机的拍照质量已经是很多人买手机的首选条件了。而对于相机而言主要有两大功能:拍照片和拍视频。Android 为此两种方式: 相机 intent相机 API 本节我们就一起来看看相机的具体用法。 1. 打开 Camer…

Leetcode—1991. 找到数组的中间位置【简单】

2024每日刷题&#xff08;129&#xff09; Leetcode—1991. 找到数组的中间位置 实现代码 class Solution { public:int findMiddleIndex(vector<int>& nums) {int sum accumulate(nums.begin(), nums.end(), 0);int prefix 0;for(int i 0; i < nums.size();…

SQL 基础 | JOIN 操作介绍

在SQL中&#xff0c;JOIN是一种强大的功能&#xff0c;用于将两个或多个表中的行结合起来&#xff0c;基于相关的列之间的关系。 JOIN操作通常用在SELECT语句中&#xff0c;以便从多个表中检索数据。 以下是几种基本的JOIN类型以及它们的用法&#xff1a; INNER JOIN&#xff1…

代码随想录:二分查找相关题目推荐(35、34)

35.搜索插入位置 题目 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target …

Flink DataSource介绍

介绍 Flink的Data Source&#xff08;数据源、源算子&#xff09;是Flink作业的起点&#xff0c;它定义了数据输入的来源。Flink可以从各种数据来源获取数据&#xff0c;例如文件系统、消息队列、数据库等。以下是对Flink Data Source的详细介绍&#xff1a; 概述&#xff1a…

深入探索:npm详解

在现代前端开发中&#xff0c;npm&#xff08;Node Package Manager&#xff09;扮演着至关重要的角色&#xff0c;它是JavaScript世界中最大的软件注册表&#xff0c;也是前端开发者分享和管理代码的主要平台。本篇博文将详细介绍npm的使用方法&#xff0c;并重点讨论如何发布…