「 关注“石杉的架构笔记”,大厂架构经验倾囊相授 」
文章来源:http://u6.gg/k5xdn
WHY?
IN 和 NOT IN 是比较常用的关键字,为什么要尽量避免呢?
| 效率低
项目中遇到这么个情况:t1表 和 t2表 都是150w条数据,600M的样子,都不算大。
select * from t1 where phone not in (select phone from t2)
十几分钟,检查了一下 phone 在两个表都建了索引,字段类型也是一样的。原来 not in 是不能命中索引的!
select * from t1
where not EXISTS (select phone from t2 where t1.phone =t2.phone)
| 容易出现问题,或查询结果有误 (不能更严重的缺点)
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)
select id1 from test1
where id1 in (select id1 from test2)
EXCUSE ME!为什么不报错?
单独查询 select id1 from test2 是一定会报错:消息 207,级别 16,状态 1,第 11 行 列名 'id1' 无效。然而使用了 IN 的子查询就是这么敷衍,直接查出 1 2 3。
这仅仅是容易出错的情况,自己不写错还没啥事儿,下面来看一下 NOT IN 直接查出错误结果的情况。
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,所以它不会输出。
跑题一句:建表的时候最好不要允许含空值,否则问题多多。
HOW?
用 EXISTS 或 NOT EXISTS 代替:
select * from test1
where EXISTS (select * from test2 where id2 = id1 )
select * FROM test1
where NOT EXISTS (select * from test2 where id2 = id1 )
用 JOIN 代替:
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 -------------
更多 Spring Cloud Alibaba 学习资料
欢迎扫码加群领取
点个在看你最好看
网友评论已有0条评论, 我也要评论