//假设一个for循环
for($i = ; $i < ; $i++)
{
for ($j = ; $i < ; $j++)
{ }
} for($i = ; $i < ; $i++)
{
for ($j = ; $i < ; $j++)
{ }
}

看以上两个for循环,总共循环的次数是一样的。但是对于mysql数据库而言,并不是这样了,我们尽量选择第②个for循环,也就是小表驱动大表。
数据库最伤神的就是跟程序链接释放,第一个建立了10000次链接,第二个建立了50次。假设链接了两次,每次做上百万次的数据集查询,查完就走,这样就只做了两次;相反建立了上百万次链接,申请链接释放反复重复,这样系统就受不了了。
这时候就诞生了in 和exists的对比。

小表驱动大表:即小的数据集驱动大的数据集。

这里假设A表代表员工表,B表代表部门表。
假设部门只有三个,销售、技术部、行政部,言下之意是在这三个部门里的所有员工都查出。

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

这样写就等价于:
for select id from B。比如华为有100个部门,但是华为的员工少说有15W-20W,员工总比部门多,这时候就相当于得到了小表(部门表);for select * from A where A.id = B.id,相当于A.id等B表里面的,相当于从部门表获得对应的id。

当B表的数据集必须小于A表的数据集时,用in优于exists。
反之

select * from A where exists (select  from B where B.id = A.id); //这里的select 1并不绝对,可以写为select 'X'或者'A','B','C'都可以,只要是常量就可以。

这样写就等价于:
for select * from A,先从A表做循环
for select * from B where B.id = A.id,再从B表做循环。
这样exists就会变成看看A表是否存在于(select 1 from B where B.id = A.id)里面,这个查询返回的是TRUE或者FALSE的BOOL值,简单来说就是要当A表的数据集小于B表的数据集时,用exists优于in。要注意的是:A表与B表的ID字段应该建立索引。

语法:EXISTS
SELECT ...FROM table WHERE EXISTS(subquery)。
理解:将主查询的数据放到子查询中做条件验证,根据验证结果(TRUE或者FALSE)来决定朱查询的数据结果是否得意保留。
相当于从表A和B中取出交集,然后再从A表中取出所在交集的部分数据,当然后面加WHERE条件还可以进一步筛选。
补充:
1:EXISTS(subquery)只返回TRUE或者FALSE,因此子查询中的SELECT * 也可以是SELECT 1或者SELECT 'X',官方说法是实际执行时会忽略SELECT清单,因此没有区别。
2:EXISTS子查询的实际执行过程可能经过了优化而不是我们理解上的逐条对比,如果担忧效率问题,可进行实际校验。
3:EXISTS子查询旺旺可以用条件表达式,其他子查询或者JOIN来替代,何种最优需要具体问题具体分析。

如果查询的两个表大小相当,那么用in和exists差别不大。

延伸举例巩固:

如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:
例如:表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列的索引。

not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。

Mysql优化原则_小表驱动大表IN和EXISTS的合理利用的更多相关文章

  1. 了解MySQL联表查询中的驱动表,优化查询,以小表驱动大表

    一.为什么要用小表驱动大表 1.驱动表的定义 当进行多表连接查询时, [驱动表] 的定义为: 1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表] 2)未指定联接条件时,行数少的表为[驱动表 ...

  2. 3.mysql小表驱动大表的4种表连接算法

    小表驱动大表 1.概念 驱动表的概念是指多表关联查询时,第一个被处理的表,使用此表的记录去关联其他表.驱动表的确定很关键,会直接影响多表连接的关联顺序,也决定了后续关联时的查询性能. 2.原则 驱动表 ...

  3. MySQL高级知识(十六)——小表驱动大表

    前言:本来小表驱动大表的知识应该在前面就讲解的,但是由于之前并没有学习数据批量插入,因此将其放在这里.在查询的优化中永远小表驱动大表. 1.为什么要小表驱动大表呢 类似循环嵌套 for(int i=5 ...

  4. MySql 小表驱动大表

    在了解之前要先了解对应语法 in 与 exist. IN: select * from A where A.id in (select B.id from B) in后的括号的表达式结果要求之输出一列 ...

  5. 6.2 小表驱动大表(exists的应用)

    1. 优化原则:小表驱动大表,即小数据集驱动大数据集. select * from A where id in (select id from B) 等价于: for select id from B ...

  6. 查询优化--小表驱动大表(In,Exists区别)

    Mysql 系列文章主页 =============== 本文将以真实例子来讲解小表驱动大表(In,Exists区别) 1 准备数据 1.1 创建表.函数.存储过程 参照  这篇(调用函数和存储过程批 ...

  7. 小表驱动大表, 兼论exists和in

    给出两个表,A和B,A和B表的数据量, 当A小于B时,用exists select * from A where exists (select * from B where A.id=B.id) ex ...

  8. hive join 优化 --小表join大表

    1.小.大表 join 在小表和大表进行join时,将小表放在前边,效率会高.hive会将小表进行缓存. 2.mapjoin 使用mapjoin将小表放入内存,在map端和大表逐一匹配.从而省去red ...

  9. 【Spark调优】小表join大表数据倾斜解决方案

    [使用场景] 对RDD使用join类操作,或者是在Spark SQL中使用join语句时,而且join操作中的一个RDD或表的数据量比较小(例如几百MB或者1~2GB),比较适用此方案. [解决方案] ...

随机推荐

  1. 《C++ Primer Plus》15.1 友元 学习笔记

    15.1.1 友元类假定需要编写一个模拟电视机和遥控器的简单程序.决定定义一个Tv类和一个Remote类,来分别表示电视机和遥控器.遥控器和电视机之间既不是is-a关系也不是has-a关系.事实上,遥 ...

  2. String.Join重载String.Join 方法 (String, String[], Int32, Int32)

    https://msdn.microsoft.com/zh-cn/library/tk0xe5h0 String.Join 方法 (String, String[], Int32, Int32) 官方 ...

  3. js基础---->js中的消息框

    可以在JavaScript 中创建三种消息框:警告框.确认框.提示框.今天我们就这几个框做一个介绍.我们笑着说再见,却深知再见遥遥无期. javascript消息框 一.警告框:警告框经常用于确保用户 ...

  4. Lucene中的域选项

    Field类是lucene在索引过程中的一个很重要的类,该类控制着域值被索引的方式 域选项主要包括以下几种选项:域索引选项.域存储选项.域的项向量选项.域的排序选项等 域索引选项:通过倒排索引来控制域 ...

  5. SpringMVC实现简单应用

    我们都知道,servlet代码一般来说只能在一个servlet中做判断去实现一个servlet响应多个请求, 但是springMVC的话还是比较方便的,主要有两种方式去实现一个controller里能 ...

  6. HDCMS留言插件的使用!

    HDCMS留言插件,JS简单示例: <img src='{|U:'code'}' onclick='this.src='{|U:'code'}&'+Math.random()' /> ...

  7. html<input>输入框中各种正则表达式设置

    <%@ page language="java" contentType="text/html; charset=gb2312" pageEncoding ...

  8. 170616、解决 java.lang.IllegalArgumentException: No converter found for return value of type: class java.util.ArrayList

    报错截图: 原因:搭建项目的时候,springmvc默认是没有对象转换成json的转换器的,需要手动添加jackson依赖. 解决步骤: 1.添加jackson依赖到pom.xml <!-- j ...

  9. HOJ 2317 Pimp My Ride(状态压缩DP)

    Pimp My Ride My Tags (Edit) Source : TUD 2005 Time limit : 3 sec Memory limit : 64 M Submitted : 63, ...

  10. Java学习记录-Lambda表达式示例

    List<Integer> userIds=userInfoList.stream().map(m->m.getUserId()).collect(Collectors.toList ...