当前位置: 首页 > 后端技术 > Java

面试官:为什么要尽量避免IN和NOTIN?大多数人都会看错!

时间:2023-04-02 10:31:12 Java

为什么?IN和NOTIN是比较常用的关键词,为什么要尽量避免呢?1、我在一个低效率的项目中遇到过这样一种情况:t1表和t2表都有150w条数据,看着600M,不算大。但是这样的查询↓select*fromt1wherephonenotin(selectphonefromt2)让我变得愚蠢。..十分钟后,我查看phone在两个表中都建立了索引,而且字段类型是一样的。结果发现notin不能命中索引。...改成NOTEXISTS后,查询耗时20s,效率真的差了很多。select*fromt1wherenotEXISTS(selectphonefromt2wheret1.phone=t2.phone)2.容易出问题,或者查询结果错误(不是更严重的缺点)。以IN为例。创建两个表:test1和test2createtabletest1(id1int)createtabletest2(id2int)insertintotest1(id1)values(1),(2),(3)insertintotest2(id2)values(1),(2)我想查询,test1中存在于test2中的id。IN的一般写法是:selectid1fromtest1whereid1in(selectid2fromtest2)结果是:OK,没有问题!但是如果我手滑写了:selectid1fromtest1whereid1in(selectid1fromtest2)不小心把id2写成了id1,会怎么样呢?结果是:对不起!为什么不报错?单独查询selectid1fromtest2肯定会报错:Msg207,Level16,State1,Line11Thecolumnname'id1'isinvalid。然而,使用IN的子查询就这么敷衍了事。直接求123只是一种容易出错的情况。test2插入空值:insertintotest2(id2)values(NULL)我要查询,test1中test2中不存在的id。selectid1fromtest1whereid1notin(selectid2fromtest2)结果是:空白!显然这个结果不是我们想要的。我们要3.为什么会这样?原因是:NULL不等于任何非空值!如果id2只有1和2,那么3<>1和3<>2所以输出3,但是id2包含null值,那么3不等于NULL所以不会输出。题外话:创建表的时候,最好不要允许空值,否则会出现很多问题。如何?1.使用EXISTS或NOTEXISTS而不是select*fromtest1whereEXISTS(select*fromtest2whereid2=id1)select*FROMtest1whereNOTEXISTS(select*fromtest2whereid2=id1)2.使用JOIN而不是selectid1fromtest1INNERJOINtest2ONid2=id1selectid1fromtest1LEFTJOINtest2ONid2=id1whereid2ISNULL没有问题!PS:所以我们不能再使用IN和NOTIN了吗?这不,曾经有位大神说过,如果是确定的、限定的收藏,就可以用。如IN(0,1,2)。作者:Hydor\出处:https://www.cnblogs.com/hydor...近期热点文章推荐:1.1000+Java面试题及答案(2022最新版)2.精彩!Java协程来了。..3.SpringBoot2.x教程,太全面了!4.不要用爆破爆满画面,试试装饰者模式,这才是优雅的方式!!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!