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

背景

研究 “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的效率更高,而且两者的执行逻辑是有区别的,有时候甚至是个大坑。
方法一执行的结果是:

有点奇怪的是null的那条记录有点意外地不在预期里头,而方法2更加符合我们的预期
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值