面试官:为什么要尽量避免使用 IN 和 NOT IN 呢?
互联网架构师
共 2061字,需浏览 5分钟
· 2022-03-01
上一篇:公司发声明了!禁止所有程序员使用 Lombok !再使用绩效直接打C!
来源:cnblogs.com/hydor/p/5391556.html
WHY?
IN 和 NOT IN 是比较常用的关键字,为什么要尽量避免呢?
1、效率低
t1表 和 t2表 都是150w条数据,600M的样子,都不算大。
但是这样一句查询 ↓
select * from t1 where phone not in (select phone from t2)
直接就把我跑傻了。。。十几分钟,检查了一下 phone在两个表都建了索引,字段类型也是一样的。原来not in 是不能命中索引的。。。。
改成 NOT EXISTS 之后查询 20s ,效率真的差好多。
select * from t1
where not EXISTS (select phone from t2 where t1.phone =t2.phone)
2、容易出现问题,或查询结果有误 (不能更严重的缺点)
以 IN 为例。建两个表:test1 和 test2
create table test1 (id1 int)
create table test2 (id2 int)
insert into test1 (id1) values (1),(2),(3)
insert into test2 (id2) values (1),(2)
select id1 from test1
where id1 in (select id2 from test2)
结果是:
OK 木有问题!
但是如果我一时手滑,写成了:
select id1 from test1
where id1 in (select id1 from test2)
EXCUSE ME!为什么不报错?
单独查询 select id1 from test2 是一定会报错: 消息 207,级别 16,状态 1,第 11 行 列名 'id1' 无效。另外,搜索公众号互联网架构师后台回复“2T”,获取一份惊喜礼包。
然而使用了IN的子查询就是这么敷衍,直接查出 1 2 3
这仅仅是容易出错的情况,自己不写错还没啥事儿,下面来看一下 NOT IN 直接查出错误结果的情况:
给test2插入一个空值:
insert into test2 (id2) values (NULL)
select id1 from test1
where id1 not in (select id2 from test2)
结果是:
空白!显然这个结果不是我们想要的。我们想要3。为什么会这样呢?
原因是:NULL不等于任何非空的值啊!如果id2只有1和2, 那么3<>1 且 3<>2 所以3输出了,但是 id2包含空值,那么 3也不等于NULL 所以它不会输出。
(跑题一句:建表的时候最好不要允许含空值,否则问题多多。)
select * from test1
where EXISTS (select * from test2 where id2 = id1 )
select * FROM test1
where NOT EXISTS (select * from test2 where id2 = id1 )
select id1 from test1
INNER JOIN test2 ON id2 = id1
select id1 from test1
LEFT JOIN test2 ON id2 = id1
where id2 IS NULL
PS:那我们死活都不能用 IN 和 NOT IN 了么?并没有,一位大神曾经说过,如果是确定且有限的集合时,可以使用。如 IN (0,1,2)。
感谢您的阅读,也欢迎您发表关于这篇文章的任何建议,关注我,技术不迷茫!小编到你上高速。
· END ·最后,关注公众号互联网架构师,在后台回复:2T,可以获取我整理的 Java 系列面试题和答案,非常齐全。
正文结束
推荐阅读 ↓↓↓
1.救救大龄码农!45岁程序员在国务院网站求助总理!央媒网评来了...
5.37岁程序员被裁,120天没找到工作,无奈去小公司,结果懵了...
6.IntelliJ IDEA 2019.3 首个最新访问版本发布,新特性抢先看
评论
红卫里
物业公司业主自管开发商单位自建小区地址河北省/秦皇岛市/海港区/文化路街道/海阳路273号物业类型公寓住宅权属类别商品房住宅竣工时间2005年产权年限70年总户数2979户总建面积暂无容积率1.20绿
红卫里
0
里洞镇洛洞村
2019年9月,洛洞村上榜2018年广东省“民主法治示范村(社区)”创建单位名单。洛洞村是广东省云浮市新兴县里洞镇下辖的行政村,城乡分类代码为220,为村庄。区划代码为445321108207,居民身
里洞镇洛洞村
0
里洞镇梧洞村
2022年10月,广东省农业农村厅认定梧洞村为2022年广东省“一村一品、一镇一业”专业村(花卉)。2019年9月,梧洞村上榜2018年广东省“民主法治示范村(社区)”创建单位名单。梧洞村是广东省云浮
里洞镇梧洞村
0
里洞镇
地名由来:里洞镇古称“里坷”,因地处山区里面的小盆地而得名。天露山天露山里洞镇位于新兴县南部,与开平、恩平、阳春三市相邻,是有名的革命老区。全镇面积128平方公里,辖8个村(居)委会,总人口18300
里洞镇
0