当前位置: 首页 > news >正文

【PostgreSQL17新特性之-冗余IS [NOT] NULL限定符的处理优化】

在执行一个带有IS NOT NULL或者NOT NULL的SQL的时候,通常会对表的每一行,都会进行检查以确保列为空/不为空,这是符合常理的。
但是如果本身这个列上有非空(NOT NULL)约束,再次检查就会浪费资源。甚至有时候走索引,但是还需要回表扫描整个表去确认是否满足NULL的条件,这个时候明显是不太合理的。

在PostgreSQL16版本及以前,就算原本的列上有非空索引,查询条件带有NULL和NOT NULL,也感知不到,依然会去扫描表去评估,增加额外的计划和执行的开销。

postgres<16.1>(ConnAs[postgres]:PID[4639] 2024-05-29/12:02:51)=# create table t1 as select * from pg_class;
SELECT 494
postgres<16.1>(ConnAs[postgres]:PID[4639] 2024-05-29/12:02:55)=#  alter table t1 alter COLUMN oid set not null;
ALTER TABLE
postgres<16.1>(ConnAs[postgres]:PID[4639] 2024-05-29/12:09:59)=# \d t1Table "public.t1"
+---------------------+--------------+-----------+----------+---------+
|       Column        |     Type     | Collation | Nullable | Default |
+---------------------+--------------+-----------+----------+---------+
| oid                 | oid          |           | not null |         |
| relname             | name         |           |          |         |
| relnamespace        | oid          |           |          |         |
| reltype             | oid          |           |          |         |
| reloftype           | oid          |           |          |         |
| relowner            | oid          |           |          |         |
| relam               | oid          |           |          |         |
| relfilenode         | oid          |           |          |         |
| reltablespace       | oid          |           |          |         |
... ...postgres<16.1>(ConnAs[postgres]:PID[4639] 2024-05-29/12:10:05)=#  explain (costs off) select * from t1 where oid IS NULL;
+-------------------------+
|       QUERY PLAN        |
+-------------------------+
| Seq Scan on t1          |
|   Filter: (oid IS NULL) |
+-------------------------+
(2 rows)postgres<16.1>(ConnAs[postgres]:PID[4639] 2024-05-29/12:11:03)=#  explain (costs off) select * from t1 where oid IS NOT NULL;
+-----------------------------+
|         QUERY PLAN          |
+-----------------------------+
| Seq Scan on t1              |
|   Filter: (oid IS NOT NULL) |
+-----------------------------+
(2 rows)

David Rowley的相关邮件里也强调了:当我们优化Min/Max聚合时,规划器添加的IS NOT NULL qual会使重写的计划忽略NULL,这可能会导致索引选择不佳的问题。特别是那些没有统计数据,让规划器估算的近似选择性的条件,可能会导致较差的索引选择,例如LIMIT 1更倾向于廉价的启动路径。

PostgreSQL: Removing const-false IS NULL quals and redundant IS NOT NULL quals

image.png

在 PostgreSQL17-beta1 中,为了改进IS [NOT] NULL涉及条件时的规划,NOT NULL首先对列进行条件检查。让planner(规划器)检查NOT NULL列,并让planner(规划器)为所有查询删除这些qual(当不需要它们时),而不仅仅是在优化最小/最大聚合时。 并且还检测NOT NULL列上的IS NULL qual,这也有助于自联接删除工作,因为它必须将严格的联接限定符替换为IS NOT NULL限定符,以确保与原始查询等效。

改进后的 PostgreSQL17-beta1 的现象如下所示:

postgres<17beta1>(ConnAs[postgres]:PID[21590] 2024-05-28/15:29:09)=# create table t1 as select * from pg_class;
SELECT 415
postgres<17beta1>(ConnAs[postgres]:PID[21590] 2024-05-28/15:29:26)=# alter table t1 alter COLUMN oid set not null;
ALTER TABLE
postgres<17beta1>(ConnAs[postgres]:PID[21590] 2024-05-28/15:29:20)=# \d t1Table "public.t1"
+---------------------+--------------+-----------+----------+---------+
|       Column        |     Type     | Collation | Nullable | Default |
+---------------------+--------------+-----------+----------+---------+
| oid                 | oid          |           | not null |         |
| relname             | name         |           |          |         |
| relnamespace        | oid          |           |          |         |
| reltype             | oid          |           |          |         |
| reloftype           | oid          |           |          |         |
| relowner            | oid          |           |          |         |
| relam               | oid          |           |          |         |
| relfilenode         | oid          |           |          |         |
| reltablespace       | oid          |           |          |         |
| relpages            | integer      |           |          |         |
| reltuples           | real         |           |          |         |
| relallvisible       | integer      |           |          |         |
... ...postgres<17beta1>(ConnAs[postgres]:PID[21590] 2024-05-28/15:29:39)=# explain (costs off) select * from t1 where oid IS NULL;
+--------------------------+
|        QUERY PLAN        |
+--------------------------+
| Result                   |
|   One-Time Filter: false |
+--------------------------+
(2 rows)postgres<17beta1>(ConnAs[postgres]:PID[21590] 2024-05-28/15:29:46)=# explain (costs off) select * from t1 where oid IS NOT NULL;
+----------------+
|   QUERY PLAN   |
+----------------+
| Seq Scan on t1 |
+----------------+
(1 row)

参考文档:
1.https://www.postgresql.org/message-id/flat/17540-7aa1855ad5ec18b4@postgresql.org
2.https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=b262ad440edecda0b1aba81d967ab560a83acb8a

相关文章:

【PostgreSQL17新特性之-冗余IS [NOT] NULL限定符的处理优化】

在执行一个带有IS NOT NULL或者NOT NULL的SQL的时候&#xff0c;通常会对表的每一行&#xff0c;都会进行检查以确保列为空/不为空&#xff0c;这是符合常理的。 但是如果本身这个列上有非空&#xff08;NOT NULL&#xff09;约束&#xff0c;再次检查就会浪费资源。甚至有时候…...

Flink的简单学习二

一 Flink的核心组件 1.1 client 1.将数据流程图DataFlow发送给JobManager。 1.2 JobManager 1.收集client的DataFlow图&#xff0c;将图分解成一个个的task任务&#xff0c;并返回状态更新数据给client 2.JobManager负责作业调度&#xff0c;收集TaskManager的Heartbeat和…...

如何提高员工的工作主动性?

在现代竞争激烈的商业环境中&#xff0c;拥有高度主动性的员工是每个组织所追求的目标。主动性不仅能够促进员工的个人成长&#xff0c;还可以提升团队的效率和创新力。因此&#xff0c;如何提高员工的工作主动性成为了企业管理者需要关注的重要问题。那么如何培养和激发员工的…...

FFmpeg PCM编码为AAC

使用FFmpeg库把PCM文件编码为AAC文件&#xff0c;FFmpeg版本为4.4.2-0 代码如下&#xff1a; #include <stdio.h> #include <stdlib.h> #include <string.h> #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <…...

React@16.x(16)Render Props

目录 1&#xff0c;问题描述2&#xff0c;解决方式2.1&#xff0c;Render Props2.2&#xff0c;HOC 3&#xff0c;使用场景 1&#xff0c;问题描述 当使用组件时&#xff0c;标签中的内容&#xff0c;会被当做 props.children 来渲染&#xff1a; 子组件&#xff1a; import…...

STM32 定时器问题

stm32通用定时器中断问题 STM32 定时器有时一开启就进中断的问题 /// STM32 TIM1高级定时器RCR重复计数器的理解 /// /// /// /// /// /// /// ///...

CSS学习笔记目录

CSS学习笔记之基础教程&#xff08;一&#xff09; CSS学习笔记之基础教程&#xff08;二&#xff09; CSS学习笔记之中级教程&#xff08;一&#xff09; CSS学习笔记之中级教程&#xff08;二&#xff09; CSS学习笔记之中级教程&#xff08;三&#xff09; CSS学习笔记之高级…...

随笔-我在武汉一周了

做梦一样&#xff0c;已经来武汉一周了&#xff0c;回顾一下这几天&#xff0c;还真是有意思。 周一坐了四个小时的高铁到了武汉站&#xff0c;照着指示牌打了个出租车。司机大姐开得很快&#xff0c;瞅了眼&#xff0c;最快速度到了110&#xff0c;差点把我晃晕。一下车就感觉…...

Python 爬虫零基础:探索网络数据的神秘世界

Python 爬虫零基础&#xff1a;探索网络数据的神秘世界 在数字化时代&#xff0c;网络数据如同无尽的宝藏&#xff0c;等待着我们去发掘。Python爬虫&#xff0c;作为获取这些数据的重要工具&#xff0c;正逐渐走进越来越多人的视野。对于零基础的学习者来说&#xff0c;如何入…...

微信小程序的view的属性值和用法

在微信小程序中&#xff0c;view 是一个基础的视图组件&#xff0c;用于承载其他视图组件或者展示文本、图片等内容。view 组件具有多种属性&#xff0c;用于控制其行为和样式。以下是一些常用的 view 属性及其用法&#xff1a; class / style: 控制视图的样式&#xff0c;可以…...

Python优化、异常处理与性能提升技巧

Python作为一种高效的编程语言&#xff0c;其灵活性和强大的功能使得它成为了许多开发者的首选。在日常的编程实践中&#xff0c;掌握一些高效的Python技巧可以极大地提升开发效率和代码质量。本文将介绍五个关于Python使用技巧&#xff0c;帮助你更加熟练地运用Python解决问题…...

Flink状态State | 大数据技术

⭐简单说两句⭐ ✨ 正在努力的小叮当~ &#x1f496; 超级爱分享&#xff0c;分享各种有趣干货&#xff01; &#x1f469;‍&#x1f4bb; 提供&#xff1a;模拟面试 | 简历诊断 | 独家简历模板 &#x1f308; 感谢关注&#xff0c;关注了你就是我的超级粉丝啦&#xff01; &a…...

go语言方法之方法值和方法表达式

我们经常选择一个方法&#xff0c;并且在同一个表达式里执行&#xff0c;比如常见的p.Distance()形式&#xff0c;实际上 将其分成两步来执行也是可能的。p.Distance叫作“选择器”&#xff0c;选择器会返回一个方法"值"->一 个将方法(Point.Distance)绑定到特定接…...

TDMQ CKafka 版弹性存储能力重磅上线!

导语 自 2024年5月起&#xff0c;TDMQ CKafka 专业版支持弹性存储能力&#xff0c;这种产品形态下&#xff0c;存储可按需使用、按量付费&#xff0c;一方面降低消费即删除、存储使用波动大场景下的存储成本&#xff0c;另一方面存储空间理论上无穷大。 TDMQ CKafka 版产品能…...

24、Linux网络端口

Linux网络端口 1、查看网络接口信息ifconfig ens33 eth0 文件 ifconfig 当前设备正在工作的网卡&#xff0c;启动的设备。 ifconfig -a 查看所有的网络设备。 ifconfig ens33 查看指定网卡设备。 ifconfig ens33 up/down 对指定网卡设备进行开关 基于物理网卡设备虚拟的…...

Mysql全文搜索和LIKE搜索有什么区别

全文搜索和LIKE的区别 性能&#xff1a;在大数据集上&#xff0c;全文搜索通常比LIKE查询更快&#xff0c;因为它使用了专门的索引结构。 功能&#xff1a;全文搜索提供了更丰富的查询功能&#xff0c;如多个关键词的搜索、自然语言搜索、布尔搜索等。而LIKE通常只支持简单的…...

elementplu父级页面怎么使用封装子组件原组件的方法

一、使用原因&#xff1a; 封装了el-table&#xff0c;表格中有多选&#xff0c;父级要根据指定状态&#xff0c;让其选择不上&#xff0c;需要用到elementplus中table原方法toggleRowSelection 附加小知识点&#xff1a;&#xff08;el-tree刷新树后之前选中的保持高亮setCurr…...

el-date-picker选择开始日期的近半年

<el-date-pickerv-model"form[val.key]":type"val.datePickerType || daterange":clearable"val.clearable && true"range-separator"~"start-placeholder"开始日期"end-placeholder"结束日期"style&q…...

C++

封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height)&#xff0c; 定义公有成员函数: 初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度的函数:set_h(int h) 输出该矩形的周长和面积函数:void show()...

nginx源码阅读理解 [持续更新,建议关注]

文章目录 前述一、nginx 进程模型基本流程二、源码里的小点1.对字符串操作都进行了原生实现2.配置文件解析也是原生实现待续 前述 通过对 nginx 的了解和代码简单阅读&#xff0c;发现这个C代码的中间件确实存在过人之处&#xff0c;使用场景特别多&#xff0c;插件模块很丰富…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

【UE5 C++】通过文件对话框获取选择文件的路径

目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 &#xff0c;这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器&#xff0c;右键点击 .uproject 文件&#xff0c;选择 "Generate Visual Studio project files"&#xff0c;重…...