SQL改写:99%DBA估计都会忽略的重大知识点

news/2025/10/28 16:54:35/文章来源:https://www.cnblogs.com/www-htz-pw/p/19172231

我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢!
由于博客中有大量代码,通过页面浏览效果更佳。

今天在给一个网友优化一条含有子查询的SQL时,用到了子查询转外连接的改写技术,被网友质疑改写where过滤行有问题。通过了解后,原来是网友对Where过滤行的理解有分歧导致的。这个分歧就是Where条件过滤行到底是对关联后的结果集进行过滤还是对关联前表上的行进行过滤呢?这个问题相信大部分DBA可能都会忽略的重大知识点,特别是原来在传统的Oracle纯运维的DBA尤为突出。今天就针对网友理解的这个知识点在PG环境中演示一下,通过执行计划来演示和说明一下。

1,结论

这里把结论放在前面,感兴趣的可以直接看结论,节约大家的时间。

  • 等值连接中where过滤条件是过滤表中的记录。
  • 在外连接中where过滤被关联表的列的IS NULL过滤时是对关联后的结果集进行过滤,其它是对过滤表中的记录。

2,创建测试表

这里就直接利用pg_class来创建两张测试表。

htz=# create table source as select * from pg_class;
SELECT 480
htz=# create table target as select *from pg_class;
SELECT 483

3,等值连接

3.1 模拟需求

查询source中relname为account,并且oid在target中存在的记录

htz=# explain analyze  select count(*) from source a join target b using(oid) where a.relname='account';QUERY PLAN                                                      
---------------------------------------------------------------------------------------------------------------------Aggregate  (cost=36.67..36.68 rows=1 width=8) (actual time=0.164..0.165 rows=1 loops=1)->  Hash Join  (cost=18.01..36.66 rows=1 width=0) (actual time=0.083..0.160 rows=1 loops=1)Hash Cond: (b.oid = a.oid)->  Seq Scan on target b  (cost=0.00..16.83 rows=483 width=4) (actual time=0.011..0.055 rows=483 loops=1)->  Hash  (cost=18.00..18.00 rows=1 width=4) (actual time=0.062..0.062 rows=1 loops=1)Buckets: 1024  Batches: 1  Memory Usage: 9kB->  Seq Scan on source a  (cost=0.00..18.00 rows=1 width=4) (actual time=0.008..0.059 rows=1 loops=1)Filter: (relname = 'account'::name)Rows Removed by Filter: 479Planning Time: 0.113 msExecution Time: 0.229 ms
(11 rows)

其实上面的SQL可以等价改写为:

explain analyze  select count(*) from (select * from source where relname='account') a join target b using(oid);

执行计划如下:

htz=# explain analyze  select count(*) from (select * from source where relname='account') a join target b using(oid);QUERY PLAN                                                     
-------------------------------------------------------------------------------------------------------------------Aggregate  (cost=36.67..36.68 rows=1 width=8) (actual time=0.586..0.588 rows=1 loops=1)->  Hash Join  (cost=18.01..36.66 rows=1 width=0) (actual time=0.345..0.582 rows=1 loops=1)Hash Cond: (b.oid = source.oid)->  Seq Scan on target b  (cost=0.00..16.83 rows=483 width=4) (actual time=0.062..0.264 rows=483 loops=1)->  Hash  (cost=18.00..18.00 rows=1 width=4) (actual time=0.256..0.257 rows=1 loops=1)Buckets: 1024  Batches: 1  Memory Usage: 9kB->  Seq Scan on source  (cost=0.00..18.00 rows=1 width=4) (actual time=0.026..0.234 rows=1 loops=1)Filter: (relname = 'account'::name)Rows Removed by Filter: 479Planning Time: 2.100 msExecution Time: 0.778 ms
(11 rows)

这里注意关键行的信息:

               ->  Seq Scan on source  (cost=0.00..18.00 rows=1 width=4) (actual time=0.026..0.234 rows=1 loops=1)Filter: (relname = 'account'::name)Rows Removed by Filter: 479

这里说明在source全表扫描,扫描完成后通过relname='account'来筛选满足条件的行,其中不满足条件的行被Filter删除了479行。

3.2 等值查询的结论

所以在等值查询中Where后面的过滤条件是直接过滤表的行。

4,外连接情况

外连接会涉及到2张表的关联,where中对2张表的过滤会带来完全不同的效果。这里我们对外连接中需要保留记录的表叫主库表,另外一张表就叫被连接表,比如在a left join b,这a就是主表,b就是被连接表;a right join b,b就是主表,a就是被连接表。where中对被驱动表中的列进行is null判断时,是对关联后的结果集进行过滤,对其它情况的过滤跟上面等值连接是一样的效果。

4.1 模拟非is null过滤需求

这里模拟一个需求就是查询target中relname为account的记录,利用oid对source进行关联,如果在source中存在,就展示source中的信息,如果不存在source返回null记录。

select * from target a  left join source b using(oid) where a.relname='account'; 

执行计划的信息如下:

htz=# explain analyze select * from target a  left join source b using(oid) where a.relname='account'; QUERY PLAN                                                    
-----------------------------------------------------------------------------------------------------------------Hash Right Join  (cost=18.05..36.66 rows=1 width=526) (actual time=0.340..0.557 rows=1 loops=1)Hash Cond: (b.oid = a.oid)->  Seq Scan on source b  (cost=0.00..16.80 rows=480 width=265) (actual time=0.015..0.179 rows=480 loops=1)->  Hash  (cost=18.04..18.04 rows=1 width=265) (actual time=0.285..0.285 rows=1 loops=1)Buckets: 1024  Batches: 1  Memory Usage: 9kB->  Seq Scan on target a  (cost=0.00..18.04 rows=1 width=265) (actual time=0.074..0.266 rows=1 loops=1)Filter: (relname = 'account'::name)Rows Removed by Filter: 482Planning Time: 0.444 msExecution Time: 0.737 ms
(10 rows)

结果跟等值连接是一样的。

4.2 结果

结论跟等值连接一样

4.3

这里模拟一个需求就是查询target中存在oid记录,如果oid在source中不存在。

select * from target a  left join source b using(oid) where b.oid is null;

对应的执行计划如下:

htz=# explain analyze  select * from target a  left join source b using(oid) where b.oid is null;QUERY PLAN                                                      
---------------------------------------------------------------------------------------------------------------------Hash Anti Join  (cost=22.80..41.47 rows=3 width=526) (actual time=1.273..1.399 rows=3 loops=1)Hash Cond: (a.oid = b.oid)->  Seq Scan on target a  (cost=0.00..16.83 rows=483 width=265) (actual time=0.025..0.114 rows=483 loops=1)->  Hash  (cost=16.80..16.80 rows=480 width=265) (actual time=1.021..1.021 rows=480 loops=1)Buckets: 1024  Batches: 1  Memory Usage: 102kB->  Seq Scan on source b  (cost=0.00..16.80 rows=480 width=265) (actual time=0.046..0.508 rows=480 loops=1)Planning Time: 0.305 msExecution Time: 1.650 ms

这里注意几个关键行的信息:

----------------------------------------Hash Anti Join  (cost=22.80..41.47 rows=3 width=526) (actual time=1.273..1.399 rows=3 loops=1)

优化器将SQL语句重新为反连接(not in /not exists),这个地方的where b.oid is null就是对整个结果集的过滤。上面的SQL语句其实可以重写为下面SQL:

 select * from target a where  not exists ( select * from source b where a.oid=b.oid);

改写后的执行计划如下:

htz=# explain analyze  select * from target a where  not exists ( select * from source b where a.oid=b.oid);QUERY PLAN                                                     
-------------------------------------------------------------------------------------------------------------------Hash Anti Join  (cost=22.80..41.47 rows=3 width=265) (actual time=0.111..0.132 rows=3 loops=1)Hash Cond: (a.oid = b.oid)->  Seq Scan on target a  (cost=0.00..16.83 rows=483 width=265) (actual time=0.007..0.032 rows=483 loops=1)->  Hash  (cost=16.80..16.80 rows=480 width=4) (actual time=0.064..0.065 rows=480 loops=1)Buckets: 1024  Batches: 1  Memory Usage: 25kB->  Seq Scan on source b  (cost=0.00..16.80 rows=480 width=4) (actual time=0.003..0.037 rows=480 loops=1)Planning Time: 0.126 msExecution Time: 0.221 ms
(8 rows)

4.4 结论

在外连接中对被连接列进行IS NULL过滤时是对关联后的结果集进行判断和过滤。

4 总结论

关于整个实验的结论,可以参考第一部分,这里简单写一下关于怎么快速的进行上面判断,只需要看执行计划是否存在表上面有Filter过滤即可。

------------------作者介绍-----------------------
姓名:黄廷忠
个人博客: (http://www.htz.pw)
CSDN地址: (https://blog.csdn.net/wwwhtzpw)
博客园地址: (https://www.cnblogs.com/www-htz-pw)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/948957.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NAS助手 — 纯血鸿蒙时代的 NAS 文件分享新方案

​ 🚀 NAS助手 — 纯血鸿蒙时代的 NAS 文件分享新方案​在当前阶段,官方尚未发布原生鸿蒙版本的 NAS 管理类应用,导致我们在日常使用中面临一些限制: 📁 无法直接将图片或视频批量上传至 NAS 🧾 办公文件传输…

2025年办公室玻璃隔断型材厂家权威推荐榜单:专业玻璃隔断/广州办公室隔断/双层玻璃百叶隔断源头厂家精选

随着现代办公环境不断升级,玻璃隔断市场需求持续增长。据行业统计数据显示,2024年全国办公室隔断市场规模突破280亿元,其中玻璃隔断占比达64%,年增长率稳定在15% 左右。广州作为粤港澳大湾区的核心城市,办公空间装…

Draco 编译及配置

1.下载Draco源码 地址:https://github.com/google/draco/tree/main 下载 Draco 1.5.7 release 或直接克隆 master 2.依赖环境 克隆源码后,打开third_party文件夹可看到其依赖的第三方库,下载源码:eigen(3.4.1) :…

第十一届中国大学生程序设计竞赛 女生专场

https://qoj.ac/contest/2564 一些题目挺经典

JAVA 对于class文件反编译,CFR 通常能产生最完整的代码。

JAVA 对于class文件反编译,CFR 通常能产生最完整的代码。Posted on 2025-10-28 16:49 且行且思 阅读(0) 评论(0) 收藏 举报推荐工具排序(按完整性) 1. CFR(最推荐) 1. 官方下载 http://www.benf.org/other/c…

2025全焊接换热器/板式换热器/清洗维修推荐榜:科睿泽换热(苏州)领跑,四大企业以高效传热赋能工业节能

随着工业领域对能效提升与低碳运营的重视,板式换热器凭借传热效率高、体积小、易维护等优势,成为化工、暖通、水处理等行业的关键设备。基于技术实力、场景适配性与行业口碑,2025 年板式换热器领域优质企业推荐如下…

2025橡胶/变形缝中埋式/中置式橡胶/预埋式橡胶/内埋式/止水带推荐榜:众航防水领跑衡水市场,四大企业以技术筑牢工程防渗防线

随着基建与建筑行业对防渗标准的日趋严格,止水带作为接缝防水关键材料,市场对其耐候性、定制化、供货效率的需求持续攀升。基于产品性能、工程案例与行业口碑,2025 年止水带领域优质企业推荐如下: 衡水众航防水材料…

2025 年 upe 超高分子量聚乙烯板,upe 板超高分子量聚乙烯板,uhmwpe 超高分子量聚乙烯板厂家最新推荐,产能、专利、环保三维数据透视

引言 超高分子量聚乙烯板(UPE/UHMWPE 板)作为运输、化工、煤炭等领域的核心耐磨材料,其品质直接影响工业生产效率。2025 年行业调研显示,市场合格产品仅占 68%,原材料掺假、性能虚标等问题仍存。本次推荐基于耐磨…

2025废气处理设备推荐榜:兴瀚环境领跑青岛市场,四大企业以技术突围环保赛道

废气治理需求升级,设备企业迎发展机遇 随着工业环保要求日趋严格,废气处理设备成为企业合规生产的核心装备,市场对高效、智能、定制化设备的需求持续攀升。基于技术创新、场景落地与行业口碑,2025 年废气处理设备领…

2025 浸没式/全/液冷超充推荐榜:中碳创新领跑 “超充之城”,四大企业解锁低碳补能新范式

随着新能源出行渗透率攀升,液冷超充以高效散热、长寿命等优势成为补能基础设施核心方向。基于技术突破与场景落地能力,2025 年液冷超充领域优质企业推荐如下: 中碳创新(北京)科技集团有限公司🌟🌟🌟🌟🌟…

【运维自动化-标准运维】各类全局变量使用说明-元变量(完结)

元变量有三种:下拉框、表格、文本值下拉框一、下拉框 支持单选和多选两种,单选模式下输出选中的 value,多选模式下输出选中 value 以逗号 ‘,’ 拼接的字符串。 该类型变量默认不支持输入任意值,仅在子流程节点配置…

2025年不变色二氧化硅厂家权威推荐榜单:通用型二氧化硅/可定制二氧化硅/高吸油二氧化硅源头厂家精选

在高端食品、制药及日化行业,不变色二氧化硅已成为品质控制的关键要素,直接关系到终端产品的稳定性和市场竞争力。 二氧化硅作为重要的功能性添加剂,其抗变色性能直接影响着终端产品的品质与寿命。根据市场调研数据…

linux系统启动卡在(1 of 2) A start job is running for .... ()

问题原因:网卡在等待连接,导致系统一直在等待。 解决方法:修改/etc/systemd/system/network-online.target.wants/systemd-networkd-wait-online.service,设置超时时间,在[Service]最后加入TimeoutStartSec=2

MES 他山之石:红日药业MES 文摘

本文以其中的制造执行层为探讨对象,其功能涵盖: 配方管理、生产管理、物料管理、质量管理、电子批记录管理、设备管理、账号管理、报表管理、排产排程、仓库管理、信息显示管理、工艺参数管理、远程监控及数据储存管…

HDMI辐射整改案例-阿赛姆电子

前言 HDMI辐射由于其传输速率为高速,所有由信号带出来的谐波分量很多,而且频率也会倍得很高。 一、HDMI端口介绍: HDMI高清晰度多媒体接口,是一种全数位化影像和声音传送接口,可以传送无压缩的音频信号及视频信号…

CF2045E 做题记录

前言 在别的博客你看不见这个玩意的 函数这个东西很烦人,\(min\) 可以很短也可以很长,有很多种方式表达,大部分题目会固定一部分问题剩下的问题可以很容易求出,通常固定的那一部分可以通过转化函数的表达形式求出,…

ASP.NET Core WebApi 集成 MCP 协议完全指南

前言 Model Context Protocol (MCP) 是一个标准化协议,让 AI 客户端(如 Claude、ChatGPT 等)能够通过统一的接口调用你的 API。本文将详细介绍如何在 ASP.NET Core WebApi 项目中集成 MCP 支持,实现 AI 与你的服务…

深入解析:数字信号处理 第一章(离散时间信号与系统)【上】

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

goldengate(ogg)日常维护

1.修改源端抽取进程从某个位置开始抽取GGSCI (rac01) 29> info extepEXTRACT EXTEP Last Started 2025-10-28 16:24 Status STOPPED Checkpoint Lag 00:00:03 (updated 00:00:36 ago) Log Read Chec…

关于curl-一个网址-报错-OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to

关于curl-一个网址-报错-OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection toPosted on 2025-10-28 16:32 520_1351 阅读(0) 评论(0) 收藏 举报背景:今天在一台Azure虚拟机上,使用curl 一个https网址时,…