1 in

文章从三方面介绍:查询集合,查询出错率,查询效率。主要讲什么时候可以用in,用in效果不佳时,用什么替代。总结出两点:

  • in后的查询集合不确定
    例如in (select…),应判断内查询与外查询的关系。当内查询的表小时(小于外查询的表),用in效率高。当外查询的表小时(小于内查询的表),用exists效率高。(因为in 先执行内查询,再执行外查询;而 exists先执行外查询再执行内查询)
  • in后的查询集合是确定且有限
    集合内的值连续时,应尽可能使用between …and 。
    集合内的值不连续时,可以用in,例如in (1,3,7)。

1.1 查询集合

in后的查询集合不确定时,例如in (select…),应判断内查询与外查询的关系。当内查询的表小时(小于外查询的表),用in效率高。当外查询的表小时(小于内查询的表),用exists效率高。(因为in 先执行内查询,再执行外查询;而 exists先执行外查询再执行内查询)
in后的查询集合是确定且有限的集合,且集合内的值连续时,应尽可能使用between …and 。
in后的查询集合是确定且有限的集合,但集合内的值不连续时,可以用in,例如in (1,3,7)。

1.2 查询出错率

SQL中用in 或 not in 容易出错,所以应尽量避免使用in或not in。什么时候可以使用?确定且有限的集合时,可以使用。如 IN (0,1,2)。

下面的例子参考自:SQL性能优化 - 避免使用 IN 和 NOT IN


一位大神曾经说过,如果是确定且有限的集合时,可以使用。如 IN (0,1,2)。
参考文献:[笔记] SQL性能优化 - 避免使用 IN 和 NOT IN

1.3 查询效率

一句话总结:in先执行子查询,再执行主查询;而exists先执行主查询,再执行子查询。

具体的:

in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。
exists先执行主查询,再根据主查询的结果,执行子查询。
具体例子,见参考文献。
应用场景:
当子查询的结果较小,且主查询的表较大且有索引时,应用in。
当主查询的结果较小,而子查询的表较大且有索引时,应用exists。

即先把大表减小,然后再去匹配另一个表。

in和exists的不同,即驱动顺序的不同(这是性能变化的关键)。如果是exists,那么以外层表为驱动表,先被访问。如果是IN,那么先执行子查询,以内层表为驱动表。
所以我们以驱动表的快速返回为目的(即越快获得驱动表,越好),那么就会考虑到索引及结果集的关系了 。另外IN时不对NULL进行处理。

in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。一直以来认为exists比in效率高的说法是不准确的。

参考文献:SQL中in和exists的区别

2 not in

2.1 查询集合中有null,不使用not in

如果查询集合中有null,不适合用not in,容易出错(查询结果为空)。例如:x not in (1,2,null)。

  1. 为什么x not in (1,2,null)会出错呢?
    因为x not in (1,2,null) 等价于x!=1 and x!=2 and x!=null ,而在sql中,对于任意x,x!=null永远为false,所以整体结果永远为false,所以查询结果永远为空。

  2. 为什么在sql中,x!=null为false呢?
    参考文献:SQL条件!=null查不出数据
    sql的逻辑表达式有三种可能值:true、false、unknown。
    其他语言的逻辑表达式都是只有两种可能值,而sql中有三种,这是sql特有的。从字面上理解unknown就是:什么都不知道。在sql中将任何值(包括null本身)与null作比较,都会返回unknown。而在查询表达式(having、where)中, unknown会被视为false。
    但是并不是所有情况下,都会将unknown视为false,在 check约束中,就会将unknown视为true。所以,在用check约束将字段设置为>=0时,还可以向该字段中插入null值,因为在check中,null>=0的结果unknown,会被视为true。

2.2 查询集合中有null,不使用not in,那用什么代替呢?

三种解决办法:

  1. 仍使用not in ,但修改sql语句。
    将in后的查询结果中的null过滤掉。
    例如:
select name from table1 where name not in (select name from table2 where name is not null
);
  1. 使用join 代替
select *
from a left join b on a.id=b.aid
where b.aid is null
用and:
select Table_A.ID,Table_A.name
from Table_A left join Table_B on Table_A.ID=Table_B.ID and Table_B.ID is null
用where:
select Table_A.ID,Table_A.name
from Table_A left join Table_B on Table_A.ID=Table_B.ID where Table_B.ID is null
  1. 使用not exists代替
共有的不要了,要独有的。
select * from a
where not exists(select 1 from b where a.col = b.col
);

SQL优化 —— in与not in相关推荐

  1. 史上最全SQL优化方案(二)

    接上篇!! 4 基础优化 a 优化思路 定位问题点吮吸:硬件–>系统–>应用–>数据库–>架构(高可用.读写分离.分库分表). 处理方向:明确优化目标.性能和安全的折中.防患未 ...

  2. 中秋节,送上一次非常有趣的SQL优化实战经历

    点击上方"搜云库技术团队",选择"设为星标" 回复"1024"或"面试题"获取4T学习资料 补充:看到好多朋友后台留言说 ...

  3. MySQL进阶SQL优化

    MySQL进阶SQL优化 查询效率分析: 子查询为确保消除重复值,必须为外部查询的每个结果都处理嵌套查询.在这种情况下可以考虑用联接查询来取代. 如果要用子查询,那就用EXISTS替代IN.用NOT ...

  4. [转]Mysql中的SQL优化与执行计划

    From : http://religiose.iteye.com/blog/1685537 一,如何判断SQL的执行效率? 通过explain 关键字分析效率低的SQL执行计划. 比如: expla ...

  5. MySQL优化篇:SQL优化流程

    MySQL中SQL优化流程 SQL优化流程如下: 慢查询的开启并捕获 explain+慢SQL分析 show profile查询SQL在MySQL服务器里面的执行细节和生命周期情况 SQL数据库服务器 ...

  6. 5大步骤+10个案例,堪称SQL优化万能公式

    作者丨狼爷 来源丨网址:https://www.cnblogs.com/powercto/p/14410128.html 一.前言 在应用开发的早期,数据量少,开发人员开发功能时更重视功能上的实现,随 ...

  7. 15 种 SQL 优化中,老司机才懂的处理技巧

    前言 SQL优化是一个大家都比较关注的热门话题,无论你在面试,还是工作中,都很有可能会遇到. 如果某天你负责的某个线上接口,出现了性能问题,需要做优化.那么你首先想到的很有可能是优化SQL语句,因为它 ...

  8. 面试官:不会看 Explain执行计划,简历敢写 SQL 优化?

    来自:程序员内点事 昨天中午在食堂,和部门的技术大牛们坐在一桌吃饭,作为一个卑微技术渣仔默默的吃着饭,听大佬们高谈阔论,研究各种高端技术,我TM也想说话可实在插不上嘴. 聊着聊着突然说到他上午面试了一 ...

  9. 大牛是怎么思考设计SQL优化方案的?

    作者:惨绿少年 https://www.cnblogs.com/clsn/p/8214048.html 在进行MySQL的优化之前,必须要了解的就是MySQL的查询过程,很多查询优化工作实际上就是遵循 ...

  10. MySQL · 性能优化· CloudDBA SQL优化建议之统计信息获取

    阿里云CloudDBA具有SQL优化建议功能,包括SQL重写建议和索引建议.SQL索引建议是帮助数据库优化器创造最佳执行路径,需要遵循数据库优化器的一系列规则来实现.CloudDBA需要首先计算表统计 ...

最新文章

  1. 如何删除一个VDP服务器
  2. C语言解析动态html,【c语言】使用gumbo解析HTML
  3. prepareStatement的用法和解释
  4. 马哥Linux学习笔记之一——关于多磁盘的组织问题
  5. 大淘宝技术发布首个基于神经渲染的3D建模产品Object Drawer,现已向学术界与普通用户开放...
  6. 工程量计算稿1.54安装教程 v1.54pjb
  7. Photoshop之快速蒙版Q
  8. Conflicting order. Following module has been added:
  9. 董树义 近代微波测量技术_本土IC领域又一关键技术获得突破!
  10. windows64位jdk678网盘下载
  11. domyPP:回归经典表格管理,以可协作表格管理项目
  12. 算法相关-互联网计算广告学
  13. 英国脱欧给云计算行业带来震动:六大典型场景解析
  14. mysql temporary_MySQL中临时表(TEMPORARY)
  15. 适合小白入行IT的几种编程语言
  16. android论文答辩ppt,导师看了100多个答辩ppt以后,给我们总结了一份论文答辩ppt指南!...
  17. 电脑office怎么考证
  18. GD32F130之Timer13定时器
  19. Win7重新受到用户追捧,竟然因为勒索病毒!
  20. G711转AAC代码总结【转】

热门文章

  1. 【C语言】#和##的作用
  2. JSP+ssm计算机毕业设计居民小区安全巡检系统服务端设计65261【源码、数据库、LW、部署】
  3. php如何给导航加链接,修改phpcms导航链接的方法
  4. 阿里云OSS 图片处理api(custom)
  5. 计算机组成原理实验:存储器扩展电路(使用译码器)
  6. python实现打卡
  7. 《JSP程序设计》手机销售网后台设计
  8. Photoshop从入门到精通所有视频教程(43G)以及素材资料免费拿
  9. Nesterov加速算法
  10. 计算机网络具备哪些要素,一个计算机网络必须具备以下3个基本要素