前言

在面试谈到sql优化的一些经验时,有些面试者会回答:写sql时,最好用exists来代替in,因为in不走索引,所以用exists的sql性能较好,那真的是这样么?

以下用AB两表,做个示例,两表都有一个id字段,而两个表都为id字段建立了索引

In

in的作用其实就是把范围内存在的数据做个返回,先看看下图的简单示例sql:

select * from A where id in (select id from B)

这句sql等价于两个循环:

for select id from B
for select * from A where A.id = B.id

其实就是对B表的id做个外层循环,而内层再嵌套一层A表的id循环,内层循环里判断A表和B表的id是否相等,相等的话就是要返回的数据。

Exists

exists的作用就是把主查询的数据,放到自查询中做条件的验证,结果是true则保留主查询中的结果,为false则不保留,以下用exists实现和in一样的效果:

select * from A where exists(select * from B where B.id = A.id)

这句sql也等价于两个循环:

for select * from A
for select * from B where B.id = A.id

其实就是对A表的id做个外层循环,而内层再嵌套一层B表的id循环,内层循环里判断B表和A表的id是否相等,相等的话就是要返回的数据。

这时引申出一个sql优化的规则:以小表驱动大表,mysql连接数会更少,sql性能会更佳

分析下,用in时,是in里面的表驱动外面的表,所以如果B表相对于A表是小表,用in比较好。而用exists时,是外面的表驱动exists里面的表,所以如果A表相对于B表是小表,则用exists比较好。

总结

明白了INEXISTS的原理后,配合上小表驱动大表的优化规则,可以得出用EXISTS或者是用IN,还需要根据表中数据情况而定。

IN适合于外表大而内表小的情况,而EXISTS适合于外表小而内表大的情况。

况且大多数时候是没法用EXISTS来替换IN的,比如如下语句

select * from user where id in(1,2,3)

这句语句没有多表连接,就不适合用EXISTS,而且坊间盛传的IN不走索引,其实也是不对的,详情见: 不要再问我 in,exists 走不走索引了。

用exists代替in真的好么?相关推荐

  1. 【转】oracle in和exists、not in和not exists原理和性能探究

    转自http://www.2cto.com/database/201310/251176.html 对于in和exists.not in和not exists还是有很多的人有疑惑,更有甚者禁用not ...

  2. CMakeListx.txt 编辑语法学习

    已hello.cpp为源文件,构建一个CMakeLists.txtcmake_minimum_required(VERSION 2.8) project(hello) add_executable(h ...

  3. CMake简介及使用实例

    1.CMake简介 CMake是一个跨平台的建构系统的工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的构建文档makefile或者project文件,描述系统建构的过程 ...

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

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

  5. MySQL not exists 真的不走索引么?

    在一些业务场景中,会使用NOT EXISTS语句确保返回数据不存在于特定集合,部分同事会发现NOT EXISTS有些场景性能较差,甚至有些网上谣言说"NOT EXISTS不走索引" ...

  6. NOT EXISTS真的不走索引么?如何优化NOT EXISTS!

    在一些业务场景中,会使用NOT EXISTS语句确保返回数据不存在于特定集合,部分同事会发现NOT EXISTS有些场景性能较差,甚至有些网上谣言说"NOT EXISTS不走索引" ...

  7. 你真的了解SQL中的EXISTS谓词吗?

    EXISTS 谓词的用法 支撑 SQL 和关系数据库的基础理论主要有两个:一个是数学领域的集合论,另一个是作为现代逻辑学标准体系的谓词逻辑(predicate logic),准确地说是"一阶 ...

  8. 多线程真的会使用CPU所有的内核吗?

    点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 来源:http://h5ip.cn/2SGY 学习多线程的时候,我们都知道如果多个线程分配到C ...

  9. 云计算时代,你真的懂 Docker 吗?

    要论云计算领域中,开发者需要具备哪些基本技能?那么 Docker 必是其一. 作为一个开源的应用容器引擎,Docker 能够让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行 ...

最新文章

  1. Exchange 2010 恢复误删除的邮箱账户及其邮箱
  2. 这所211高校通知不放寒假!校园将实行封闭管理!
  3. Android自己定义组件系列【2】——Scroller类
  4. c++ string类 用法简介
  5. 18、Java并发性和多线程-饥饿与公平
  6. 盐城工学院计算机基础试卷,大学计算机基础及实用软件/大学计算机基础
  7. 软件工程随堂小作业—— 寻找“水王”(C++)
  8. Ubuntu 14.04安装和卸载搜狗拼音输入法
  9. eclipse开发SVN下文件显示修改时间和提交作者的方法
  10. opencv 2 归一化函数normalize详解
  11. UDS与DoIp整理
  12. ppt转pdf使用哪种pdf虚拟打印机
  13. [从头读历史] 第263节 左传 [BC537至BC479]
  14. Java高级编程9-姜国海 网络应用编程
  15. 1024程序员节:向改变世界的程序员致敬
  16. 乐理知识(和弦相关)
  17. php上传文件到七牛云,如何使用php上传大文件到七牛云储?
  18. 【观察】从最佳实践走向行业赋能,华为重构数字化办公新体验
  19. idea中如何删除工程
  20. html5插入页头图片,HTML5 固定页头+灰度模糊效果的照片墙+悬停呈现原照

热门文章

  1. GiveMeSomeCredit——信用评分卡模型
  2. 常用的 Python 标准库都有哪些?
  3. 数电快速入门(二)(复合逻辑运算和逻辑代数的基本定律的介绍)
  4. 知识付费领域市场格局与投资观察
  5. Linux时间函数time()、ctime()、ctime_r()、localtime()、localtime_r()、asctime()、strftime()的转换关系
  6. 5·17电信日 | 中国联通谈5G
  7. DataGrid 数据绑定使用小结二(自定义列)
  8. java 网格布局管理器,Java图形化界面设计——布局管理器之GridLayout(网格布局)...
  9. UWB地铁隧道人员定位实现运营人员健康智能监测
  10. 关于双边滤波的一些理解