SQL  in与exists相关性能问题总结

  • in 和 exists

in 和 exists的是DBA或开发人员日常工作学习中常用的基本运算符,今天我就这两个所带来的性能问题进行分析总结,方便自己与他人的后续学习与工作。

先来了解in 和 exists的性能区别: 如果主查询中的表较大且又有索引,子查询得出的结果集记录较少时,应该用in;反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists。

举例说明: select * from A where A.ID in(select B.ID from B )

select * from A  where exists(select 1 from B where A.ID=B.ID)

  其中,第一句in字句使用的是外层A表的索引,括号中的B全表扫描,所以,当A表巨大而B表很小的时候,此时性能较高,反之性能很差;

第二句exists字句中使用的是内层B表的索引,外面A全表扫描,所以,当B表巨大而A表很小的时候,此时性能较高,反之性能很差。

区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是in,那么先执行子查询,再以in为驱动表,去查找外层表中符合要求的记录,所以我们会以驱动表的快速返回为目标,那么就会考虑到索引及结果集的关系了。

a)         in的执行顺序:

1.首先执行一次子查询,子查询先产生结果集;

2. 然后主查询再去结果集里去找符合要求的字段列表去.符合要求的输出,反之则不输出。

b)        exists的执行顺序:

1.首先执行一次外部查询;

2.对于外部查询中的每一行分别执行一次子查询,而且每次执行子查询时都会引用外部查询中当前行的值;

3.使用子查询的结果true或false来确定外部查询的结果集。

例如:表A(小表),表B(大表)
select * from A where cc in(select cc from B)
-->效率低,用到了A表上cc列的索引;
select * from A where exists(select cc from B where cc=A.cc)
-->效率高,用到了B表上cc列的索引。
相反的:
select * from B where cc in(select cc from A)
-->效率高,用到了B表上cc列的索引
select * from B where exists(select cc from A where cc=B.cc)
-->效率低,用到了A表上cc列的索引。

exists适合外表结果集很小的情况;in适合外表结果集很大,而内表结果集较小的情况。

  • not in 和not exists

这里首先要说,not in 逻辑上不完全等同于not exists,当子查询中返回的任意一条记录含有空值,则not in查询将不返回任何记录;当子查询字段有非空限制,这时可以使用not in。

1、对于not exists查询,内表存在空值对查询结果没有影响;对于not in查询,内表存在空值将导致最终的查询结果为空。

2、对于not exists查询,外表存在空值,存在空值的那条记录最终会输出;对于not in查询,外表存在空值,存在空值的那条记录最终将被过滤,其他数据不受影响。

3、解释为什么not in语句比not exists语句效率差这么多(not in 不走索引):

not exists语句很显然就是一个简单的两表关联,内表与外表中存在空值本身就不参与关联;

not exists的执行顺序是:在表中查询,是根据索引查询的,如果存在就返回true,如果不存在就返回false,不会每条记录都去查询。

not in的执行顺序是:是在表中一条记录一条记录的查询(查询每条记录)符合要求的就返回结果集,不符合的就继续查询下一条记录,直到把表中的记录查询完。也就是说为了证明找不到,所以只能查询全部记录才能证明,并没有用到索引。

SQL in与exists相关性能问题总结的更多相关文章

  1. SQL Server-聚焦EXISTS AND IN性能分析(十六)

    前言 前面我们学习了NOT EXISTS和NOT IN的比较,当然少不了EXISTS和IN的比较,所以本节我们来学习EXISTS和IN的比较,简短的内容,深入的理解,Always to review ...

  2. 你真的会玩SQL吗?EXISTS和IN之间的区别

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  3. SQL Server 2016 查询存储性能优化小结

    SQL Server 2016已经发布了有半年多,相信还有很多小伙伴还没有开始使用,今天我们来谈谈SQL Server 2016 查询存储性能优化,希望大家能够喜欢 作为一个DBA,排除SQL Ser ...

  4. 认识loadrunner及相关性能参数

    认识loadrunner及相关性能参数 LoadRunner,是一种预测系统行为和性能的负载测试工具.通过以模拟上千万用户实施并发负载及实时性能监测的方式来确认和查找问题,LoadRunner能够对整 ...

  5. SQL 子查询 EXISTS 和 NOT EXISTS

    MySQL EXISTS 和 NOT EXISTS 子查询语法如下: SELECT … FROM table WHERE EXISTS (subquery) 该语法可以理解为:将主查询的数据,放到子查 ...

  6. SQL数据同步到ELK(四)- 利用SQL SERVER Track Data相关功能同步数据(上)

    一.相关文档 老规矩,为了避免我的解释误导大家,请大家务必通过官网了解一波SQL SERVER的相关功能. 文档地址: 整体介绍文档:https://docs.microsoft.com/en-us/ ...

  7. 转 使用SQL从AWR收集数据库性能变化趋势

    使用SQL从AWR收集数据库性能变化趋势 为了对数据库一段时间的性能情况有个全面了解,显然AWR是一个非常有用的工具, 但很多人只会在数据库有性能问题时才会生成问题时段的awr报告去分析.虽然AWR ...

  8. MySQL 笔记整理(18) --为什么这些SQL语句逻辑相同,性能却差异巨大?

    笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 18) --为什么这些SQL语句逻辑相同,性能却差异巨大? 本篇我们以三 ...

  9. 性能测试 CentOS下结合InfluxDB及Grafana图表实时展示JMeter相关性能数据

    CentOS下结合InfluxDB及Grafana图表实时展示JMeter相关性能数据   by:授客 QQ:1033553122 实现功能 1 测试环境 1 环境搭建 2 1.安装influxdb ...

随机推荐

  1. javap 可以打印出用于jni调用的java函数的签名信息

    javap可以打印出java的字节码: -c     Prints out disassembled code, i.e., the instructions that comprise the Ja ...

  2. JDBC学习笔记(3)——复习和练习

    复习和练习 复习部分 一.获取数据库连接 1)方式一 // 获取数据库连接 @Test public void testGetConnection() throws Exception { // 1. ...

  3. 修改浏览器accept使支持@ResponseBody

    原始:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 application/json,text/javascript, ...

  4. [转]eclipse中使用maven插件的时候,运行run as maven build的时候报错

    转至:http://fxb4632242.iteye.com/blog/2193945 -Dmaven.multiModuleProjectDirectory system propery is no ...

  5. C语言简单实现sizeof功能代码

    sizeof不是函数,而是运算符,C/C++语言编译器在预编译阶段的时候就已经处理完了sizeof的问题,也就是说sizeof类似于宏定义. 下面给出一个sizeof的一个宏定义实现版本 #defin ...

  6. 字串数_hdu_1261(大数极致).java

    字串数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  7. 【M22】考虑以操作符复合形式(op=)取代其独身形式(op)

    1.对于内置类型,x = x+y 与x+=y的结果相同. 2. x=x+y 与 x+=y的结果相同,但二者做的事情差别很大. a.x=x+y做的事情:方法内有个局部对象,值为x+y,返回局部对象,返回 ...

  8. Codeforces Testing Round #12 A. Divisibility 水题

    A. Divisibility Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/597/probl ...

  9. Codeforces Round #250 (Div. 1) B. The Child and Zoo 并查集

    B. The Child and Zoo Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/438/ ...

  10. 密码强度应用(js)

    <!-- 密码强度div --> <div id="tips" class="help-block"> <b class=&quo ...