MySQL 查询两个表的差集
参考文章里作者是这样写的:
a 左连接 b,查询 a 中没有的 b 记录
select id,`name` FROM a LEFT JOIN
(select id as i FROM b) as c
ON a.id=c.i where c.i IS NULL;
b 左连接 a,查询 b 中没有的 a 记录
select id,`name` FROM b LEFT JOIN
(select id as i FROM a) as c
ON b.id=c.i where c.i IS NULL;
为什么不直接用左连接查询呢?一开始我以为是判断字段为空的条件限制,后来直接去掉子查询发现查询结果集一致,速度反而快了 N 多倍。
测试过程如下:
测试工具:Navicat
数据库存在这样两个表 member 和 company,分别存储会员账号信息和会员公司信息,数据记录都在 4 万 - 5 万的样子。
发现存在 uid 记录不完整的情况,即 member 表存在记录,但 company 表不存在;相反的情况也是。
先是用参考文档里的模式,复刻了一版查询 sql:
select uid FROM member LEFT JOIN
(select uid as i FROM company) as t1
ON member.uid=t1.i where t1.i IS NULL;
查询时间为 48 秒左右。
然后去掉里面的子查询
select member.uid FROM member LEFT JOIN
company as t1
ON member.uid=t1.uid where t1.uid IS NULL;
查询时间为 0.001 秒,内容与添加了子查询的结果一致。
再尝试被原作者摒弃的效率很低的 where not in
模式:
select member.uid FROM member NOT IN
(select uid as i FROM company) ;
查询时间为 0.052 秒,内容与添加了子查询的结果一致。
从结果去分析,查询效率对比,直接左连接 > where not in
> 左连接子查询。
从结果推测,原作者要么是因为当时 MySQL 版本不支持直接左连接(应该不会吧!),要么就是误用了子查询。
参考文章:Mysql 求两个表(查询结果)的差集
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。