点击上方“Java精选”,选择“设为星标”

别问别人为什么,多问自己凭什么!

下方有惊喜,留言必回,有问必答!

每一天进步一点点,是成功的开始...

IN 和 NOT IN 是比较常用的关键字,为什么要尽量避免呢?

1. 效率低

项目中遇到这么个情况:

t1表 和 t2表  都是150w条数据,600M的样子,都不算大。

但是这样一句查询 ↓

select * from t1 where phone not in (select phone from t2)

直接就把我跑傻了。。。十几分钟,检查了一下  phone在两个表都建了索引,字段类型也是一样的。原来not in 是不能命中索引的。。。。

推荐下自己做的 Spring boot 的实战项目:
https://gitee.com/yoodb/jing-xuan‍

改成 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)

我想要查询,在test2中存在的  test1中的id 。使用IN的一般写法是:

select id1 from test1
where id1 in (select id2 from test2)

结果是:

OK 木有问题!

但是如果我一时手滑,写成了:

select id1 from test1
where id1 in (select id1 from test2)

不小心把id2写成id1了 ,会怎么样呢?

结果是:

EXCUSE ME!为什么不报错?

单独查询 select id1 from test2 是一定会报错: 消息 207,级别 16,状态 1,第 11 行 列名 'id1' 无效。另外,更多sql方面的面试题,公众号Java精选,回复java面试,支持在线随时随地刷题。

然而使用了IN的子查询就是这么敷衍,直接查出 1 2 3

这仅仅是容易出错的情况,自己不写错还没啥事儿,下面来看一下 NOT IN 直接查出错误结果的情况:

给test2插入一个空值:

insert into test2 (id2) values (NULL)

我想要查询,在test2中不存在的  test1中的id 。

select id1 from test1
where id1 not in (select id2 from test2)

结果是:

空白!显然这个结果不是我们想要的。我们想要3。为什么会这样呢?

推荐下几个月熬夜整理的近 10000+ 面试资料大全:https://gitee.com/yoodb/eboo‍ks

原因是:NULL不等于任何非空的值啊!如果id2只有1和2, 那么3<>1 且 3<>2 所以3输出了,但是 id2包含空值,那么 3也不等于NULL 所以它不会输出。

跑题一句:建表的时候最好不要允许含空值,否则问题多多。

HOW?

1. 用 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 )

2. 用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)。

作者:Hydor

https://www.cnblogs.com/hydor/p/5391556.html

公众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!

------ THE END ------

精品资料,超赞福利!

>Java精选面试题<
3000+ 道面试题在线刷,最新、最全 Java 面试题!

期往精选  点击标题可跳转

【258期】如何利用自定义注解放行 Spring Security项目的接口?

【259期】揭秘 MySQL 中 count 是怎样执行的?

【260期】PageHelper 使用 ThreadLocal 的线程复用问题,你用对了吗?

【261期】为什么 BigDecimal 类不能使用 equals() 方法做等值比较?

【262期】面试官:jwt 是什么?java-jwt 呢?懵逼了。。。

【263期】面试官问:假设有一千万数据,怎么快速查询?

【264期】面试官问:Spring Boot 启动时自动执行代码方式有哪几种?解释一二!

【265期】面试官:列举 8 种 Docker 应用场景,你对哪些有了解?

 技术交流群!

最近有很多人问,有没有读者交流群!想知道如何加入?方式很简单,兴趣相投的朋友,只需要点击下方卡片,回复“加群”,即可无套路入交流群!

文章有帮助的话,在看,转发吧!

【266期】面试官问:为什么 SQL 要尽量避免使用 IN 和 NOT IN?相关推荐

  1. sql参数化还是被注入了_面试官问你 SQL 注入攻击了吗?

    目录 为什么要聊 SQL 注入攻击? 什么是 SQL 注入攻击? 如何进行 SQL 注入攻击? 如何防范? 常见面试题 瞎比比 为什么要聊 SQL 注入攻击? 我这人有个想法,就是不管自己跳不跳槽,每 ...

  2. pl sql入门比较好的书_面试官问你SQL?这几本书足够了

    程序员书库(ID:CodingBook) 猿妹编译链接:https://www.lifewire.com/best-sql-books-4177471 结构化查询语言(Structured Query ...

  3. 【059期】面试官问:序列化是什么,为什么要序列化,如何实现?

    >>号外:关注"Java精选"公众号,回复"面试资料",免费领取资料!"Java精选面试题"小程序,3000+ 道面试题在线刷, ...

  4. 【263期】面试官问:假设有一千万数据,怎么快速查询?

    点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每一天进步一点点,是成功的开始... 前言 面试 ...

  5. 【255期】面试官问:MyBatis 二级缓存,如何实现关联刷新功能?

    点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每一天进步一点点,是成功的开始... 1.MyB ...

  6. 【169期】面试官问:说说为什么要限流,有哪些解决方案?

    点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜留言必回,有问必答! 每天 08:35 更新文章,每天进步一点点... ...

  7. java执行sql文件_面试官问你MyBatis SQL是如何执行的?把这篇文章甩给他

    初识 MyBatis MyBatis 是第一个支持自定义 SQL.存储过程和高级映射的类持久框架.MyBatis 消除了大部分 JDBC 的样板代码.手动设置参数以及检索结果.MyBatis 能够支持 ...

  8. 【154期】面试官问:请你说说 B 树、B+ 树的原理及区别?

    点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方留言必回,有问必答! 每天 08:35 更新文章,每天进步一点点... 之前在 ...

  9. 【020期】面试官问:Java 遍历 Map 集合有几种方式?效率如何?

    >>号外:关注"Java精选"公众号,回复"2021面试题",领取免费资料!"Java精选面试题"小程序,3000+ 道面试题在 ...

最新文章

  1. mysql学习【第14篇】:pymysql
  2. IO-5(InputStreamReader、OutputStreamWriter、序列化流、反序列化流、Serializable、transient)
  3. boost::mpl模块contains相关的测试程序
  4. 系统中常用操作基类(SSH项目中)非常非常经典的部分
  5. 无代码iVX编程实现简单 小蜜蜂 经典游戏
  6. nemesis什么车_狂野飙车9TrionNemesis介绍 S级车Trion复仇女神属性详解
  7. tez什么意思_Tezos 与 Ethereum 的区别
  8. spark学习-38-Spark的MemoryManager
  9. php中背景图怎么设置不重复,css 图像不重复怎么设置
  10. h2database源码浅析:TransactionMap、MVMap、MVStore
  11. Spring配置XML本地提示:点击eclipse属性——选择XML Catalog
  12. 暑假学习打卡【3】——北理工乐学第三周作业
  13. 无线网络密码破解方法
  14. 超酷,用 Python 教你绘制皮卡丘和哆啦A梦
  15. 4k hidpi 黑苹果_黑苹果 篇四:开启mac下的2k hidpi选项,同时开启144hz
  16. winpe装双系统linux_winPE+ubuntu双系统U盘制作
  17. python入门指南by许半仙-《江火欲燃山》《这题超纲了》《Python入门指南》
  18. 自建私有云与公有云托管对比_云托管:利与弊
  19. 京东上什么卖得最好?
  20. H3C交换机如何查环路

热门文章

  1. 《让子弹飞》系列——杀人不眨眼的老四
  2. mongodb切片问题
  3. PMP项目管理认证费多少钱?证书到期了怎么办
  4. 微博数据分析及高效获取
  5. 嵌入式软件工程师面试必备技能
  6. 2020年上海交通大学计算机软件学院夏令营面经
  7. 爬虫:东方财富网股票数据爬取
  8. 引部机壳的加工工艺规程及数控编程(论文+DWG图纸+任务书+工序卡)
  9. kernelbasedll下载_kernelbase.dll下载_kernelbase.dll修复工具下载-太平洋下载中心
  10. 利用python自带的库sympy,求解不同阻尼比的振动方程表达式