研究 “B表里的数据是否全部都在A表里“ 的问题

有目标就不怕路远。年轻人.无论你现在身在何方.重要的是你将要向何处去。只有明确的目标才能助你成功。没有目标的航船.任何方向的风对他来说都是逆风。因此,再遥远的旅程,只要有目标.就不怕路远。没有目标,哪来的劲头?一车尔尼雷夫斯基

导读:本篇文章讲解 研究 “B表里的数据是否全部都在A表里“ 的问题,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

背景

研究 “B表里的数据是否全部都在A表里” 的问题,那种写法比较合理效率高?

假设有A表和B表,B表通过自身外键和A表关联,查出B表中的外键值不在A中的。

过程

假设我们有t_master和t_pet表,即主人和宠物表,t_pet通过master_id跟t_master的id关联。假设不做数据库层面的外键约束,则有可能出现一种情况:t_pet中某些数据找不到对应的t_master记录。

建表语句如下(实验的数据库是pgsql

create table t_master(
id serial,
name varchar(32),
constraint t_master_pk primary key(id)
);


create table t_pet(
id serial,
master_id int4,
name varchar(32),
constraint t_pet_pk primary key(id)
);


insert into t_master(name) values('Stone');
insert into t_pet(master_id,name) values(1,'Tom');
insert into t_pet(master_id,name) values(2,'Jerry');
insert into t_pet(master_id,name) values(null,'Peppa');

1、写法1

我们一般会写如下的语句,但是我觉得这种语句的效率不高

select * from t_pet where master_id not in (select id from t_master);

这种是通过子查询的方式,子查询应该是需要中间在内存中缓存中间结果,我觉得这种执行效率不高,而且一般in和not in都不建议里面的元素太多,阿里巴巴的开发文档好像建议是不超过3000个。

这个请自行查看执行计划研究下,由于笔者用pg,不太方便去查看执行计划,就请读者自行对比其执行计划和第二种写法的执行计划。

2、写法2

select * from t_pet a 
where not exists (select 1 from t_master b where b.id=a.master_id);

利用not exists来实现。这种我认为效率是比方法1高非常多的。

3、补充

补充上述两种写法的差别,不仅仅是方法2的效率更高,而且两者的执行逻辑是有区别的,有时候甚至是个大坑。
方法一执行的结果是:
研究 “B表里的数据是否全部都在A表里“ 的问题
有点奇怪的是null的那条记录有点意外地不在预期里头,而方法2更加符合我们的预期
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/135028.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!