查询优化--小表驱动大表(In,Exists区别)
===============
本文将以真实例子来讲解小表驱动大表(In,Exists区别)
1 准备数据
1.1 创建表、函数、存储过程
参照 这篇(调用函数和存储过程批量插入数据) 文章中的第 1-7 步,注意,不要执行第8步
1.2 插入数据
现在来执行第8步。
1.2.1 向 Department 表中插入 100 条记录
CALL insert_dept(1000, 100)
1.2.2 向 Employee 表中插入 100000 条记录
CALL insert_employee(100000000, 100000);
2 测试
2.1 查询所有 Employee 信息,要求是:Employee 的 dept_id 存在于 Department 表中
Case#1:用 IN
SELECT * FROM employee WHERE dept_id IN (SELECT id FROM department);
结果:在我本机测试了数十次,耗时大概是 120--130 ms
Case#2:用 EXISTS
SELECT * FROM employee e WHERE EXISTS (SELECT 1 FROM department d WHERE e.dept_id = d.id);
结果:在我本机测试了数十次,耗时大概是 350--370 ms
2.2 查询所有 Department 信息,要求是:至少有一条 Employee 记录的 dept_id 对应 Department(或者说:此部门下至少有一条员工记录)
Case#3:用 EXISTS
SELECT * FROM department d WHERE EXISTS (SELECT 1 FROM employee e WHERE d.id = e.dept_id);
结果:在我本机测试了数十次,耗时大概是 4--6 ms
Case#4:用 IN
SELECT * FROM department WHERE id IN (SELECT dept_id FROM employee);
结果:在我本机测试了数十次,耗时大概是 50--55 ms
2.3 分析并总结
在 Case#1,#2 中,Employee 是大表,Department 是小表,用 IN(Department) 的效果较好(大概是用 EXISTS 时间的三分之一)====> IN 后面跟小表~
在 Case#3,#4 中,Employee 是大表,Department 是小表,用 EXISTS(Employee) 的效果较好(大概是用 IN 时间的十分之一)====> EXISTS 后面跟大表~
记忆:IN 后面跟小表~EXISTS 后面跟大表~~~因为 IN 这个单词比 EXISTS 单词更短(更小),EXISTS 这个单词比 IN 更长(更大)
2.4 进一步分析
至于为什么 Case#1 优于 Case#2,Case#3 优于 Case#4,还没搞清楚到底是为什么,,,,,TODO
一篇文章可供参考:https://www.cnblogs.com/beijingstruggle/p/5885137.html
3 结论
小表驱动大表
IN 小 EXISTS 大
查询优化--小表驱动大表(In,Exists区别)的更多相关文章
- 6.2 小表驱动大表(exists的应用)
1. 优化原则:小表驱动大表,即小数据集驱动大数据集. select * from A where id in (select id from B) 等价于: for select id from B ...
- Mysql优化原则_小表驱动大表IN和EXISTS的合理利用
//假设一个for循环 ; $i < ; $i++) { ; $i < ; $j++) { } } ; $i < ; $i++) { ; $i < ; $j++) { } } ...
- MySQL高级知识(十六)——小表驱动大表
前言:本来小表驱动大表的知识应该在前面就讲解的,但是由于之前并没有学习数据批量插入,因此将其放在这里.在查询的优化中永远小表驱动大表. 1.为什么要小表驱动大表呢 类似循环嵌套 for(int i=5 ...
- MySql 小表驱动大表
在了解之前要先了解对应语法 in 与 exist. IN: select * from A where A.id in (select B.id from B) in后的括号的表达式结果要求之输出一列 ...
- 了解MySQL联表查询中的驱动表,优化查询,以小表驱动大表
一.为什么要用小表驱动大表 1.驱动表的定义 当进行多表连接查询时, [驱动表] 的定义为: 1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表] 2)未指定联接条件时,行数少的表为[驱动表 ...
- 3.mysql小表驱动大表的4种表连接算法
小表驱动大表 1.概念 驱动表的概念是指多表关联查询时,第一个被处理的表,使用此表的记录去关联其他表.驱动表的确定很关键,会直接影响多表连接的关联顺序,也决定了后续关联时的查询性能. 2.原则 驱动表 ...
- 小表驱动大表, 兼论exists和in
给出两个表,A和B,A和B表的数据量, 当A小于B时,用exists select * from A where exists (select * from B where A.id=B.id) ex ...
- 【Spark调优】小表join大表数据倾斜解决方案
[使用场景] 对RDD使用join类操作,或者是在Spark SQL中使用join语句时,而且join操作中的一个RDD或表的数据量比较小(例如几百MB或者1~2GB),比较适用此方案. [解决方案] ...
- hive join 优化 --小表join大表
1.小.大表 join 在小表和大表进行join时,将小表放在前边,效率会高.hive会将小表进行缓存. 2.mapjoin 使用mapjoin将小表放入内存,在map端和大表逐一匹配.从而省去red ...
随机推荐
- centos7.4下离线安装CDH5.7
(一)安装前的规划 (1)操作系统版本:centos7.4(64bit) [root@hadoop22 etc]# more /etc/centos-release CentOS Linux rele ...
- Django之Model进阶的更多操作
Django之Model进阶的更多操作 一.字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) ...
- SpringBoot集成Mybatis
1.创建SpringBoot工程 根据 http://www.cnblogs.com/vitasyuan/p/8765329.html 说明创建SpringBoot项目. 2.添加相关依赖 在pom. ...
- Java面向对象之封装 入门实例(一)
一.基础概念 (一)面向对象的三大特征: 1.封装 2.继承 3.多态 (二)封装:隐藏实现细节,对外提供公共的访问方式(接口). 封装的体现之一:将属性都 ...
- String、StringBuffer、StringBulider之间的联系和区别
首先,我们大概总体的解释一下这三者的区别和联系 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间. StringBuf ...
- PhantomJS命令行选项
支持命令行选项有: --help或-h列出所有可能的命令行选项.立即停止,不会运行一个脚本作为参数传递. --version或-v打印的版本PhantomJS.立即停止,不会运行一个脚本作为参数传递. ...
- Canvas-自由绘制
#自由绘制 from tkinter import * master=Tk() c=Canvas(master,width=400,height=200) c.pack() def paint(eve ...
- jquery的attr()方法
一.定义和用法 attr() 方法设置或返回被选元素的属性和值. 当该方法用于返回属性值,则返回第一个匹配元素的值. 当该方法用于设置属性值,则为匹配元素设置一个或多个属性/值对. 二.语法 返回属性 ...
- jacascript 构造函数、原型对象和原型链
前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 先梳理一下定义: 我们通常认为 object 是普通对象,function 是函数对象: Function ...
- C# Hex编码和解码
/// 从字符串转换到16进制表示的字符串 /// 编码,如"utf-8","gb2312" /// 是否每字符用逗号分隔 public static stri ...