Mysql优化原则_小表驱动大表IN和EXISTS的合理利用
//假设一个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的合理利用的更多相关文章
- 了解MySQL联表查询中的驱动表,优化查询,以小表驱动大表
一.为什么要用小表驱动大表 1.驱动表的定义 当进行多表连接查询时, [驱动表] 的定义为: 1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表] 2)未指定联接条件时,行数少的表为[驱动表 ...
- 3.mysql小表驱动大表的4种表连接算法
小表驱动大表 1.概念 驱动表的概念是指多表关联查询时,第一个被处理的表,使用此表的记录去关联其他表.驱动表的确定很关键,会直接影响多表连接的关联顺序,也决定了后续关联时的查询性能. 2.原则 驱动表 ...
- MySQL高级知识(十六)——小表驱动大表
前言:本来小表驱动大表的知识应该在前面就讲解的,但是由于之前并没有学习数据批量插入,因此将其放在这里.在查询的优化中永远小表驱动大表. 1.为什么要小表驱动大表呢 类似循环嵌套 for(int i=5 ...
- MySql 小表驱动大表
在了解之前要先了解对应语法 in 与 exist. IN: select * from A where A.id in (select B.id from B) in后的括号的表达式结果要求之输出一列 ...
- 6.2 小表驱动大表(exists的应用)
1. 优化原则:小表驱动大表,即小数据集驱动大数据集. select * from A where id in (select id from B) 等价于: for select id from B ...
- 查询优化--小表驱动大表(In,Exists区别)
Mysql 系列文章主页 =============== 本文将以真实例子来讲解小表驱动大表(In,Exists区别) 1 准备数据 1.1 创建表.函数.存储过程 参照 这篇(调用函数和存储过程批 ...
- 小表驱动大表, 兼论exists和in
给出两个表,A和B,A和B表的数据量, 当A小于B时,用exists select * from A where exists (select * from B where A.id=B.id) ex ...
- hive join 优化 --小表join大表
1.小.大表 join 在小表和大表进行join时,将小表放在前边,效率会高.hive会将小表进行缓存. 2.mapjoin 使用mapjoin将小表放入内存,在map端和大表逐一匹配.从而省去red ...
- 【Spark调优】小表join大表数据倾斜解决方案
[使用场景] 对RDD使用join类操作,或者是在Spark SQL中使用join语句时,而且join操作中的一个RDD或表的数据量比较小(例如几百MB或者1~2GB),比较适用此方案. [解决方案] ...
随机推荐
- AFNetworking 上传文件
本文转载至 http://blog.csdn.net/hmt20130412/article/details/36487055 文件上传AFNetworking @第一种:我的 #pragma mar ...
- x64dbg使用心得
使用ScyllaHide插件时 注意一下事项 xdbg64设置里启动 附加必须第一次断下在 系统断点 然后再启用ScyllaHide. 停止调试 脱离时.必须关闭ScyllaHide 否则会报异常 x ...
- Elasticsearch配置参数介绍
Elasticsearch的config文件夹里面有两个配置文件:elasticsearch.yml和logging.yml.第一个是es的基本配置文件,第二个是日志配置文件,es也是使用log4j来 ...
- mysql报错sql injection violation, syntax error: syntax error, expect RPAREN, actual IDENTIFIER
mysql报错sql injection violation, syntax error: syntax error, expect RPAREN, actual IDENTIFIER 处理,在控制台 ...
- nexus使用方法
转自:https://www.cnblogs.com/grey-wolf/p/6481166.html centos7搭建nexus maven私服 前置条件: 1.安装jdk,可参考 http: ...
- oracle的cursor
oracle的cursor 转自:http://www.cnblogs.com/shengtianlong/archive/2010/12/31/1922767.html 1,什么是游标? ①从表中检 ...
- Spring项目对JDBC的支持和基本使用
欢迎查看Java开发之上帝之眼系列教程,如果您正在为Java后端庞大的体系所困扰,如果您正在为各种繁出不穷的技术和各种框架所迷茫,那么本系列文章将带您窥探Java庞大的体系.本系列教程希望您能站在上帝 ...
- Linux环境下安装Redis并完成测试(已验证)
准备工作: 本人测试环境:Win7 xshell远程登录Linux Linux: ubuntu 软件包:redis-3..2.6.tar.gz (Linux下redis安装包) =========== ...
- linux中增加swap分区文件的步骤方法
一.swap交换分区 Swap分区在系统的物理内存不够用的时候,把硬盘空间中的一部分空间释放出来,以供当前运行的程序使用.那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临 ...
- 170802、Elasticsearch5.2.2 安装问题记录
使用Elasticsearch5.2.2 必须安装jdk1.8 [elsearch@vm-mysteel-dc-search01 bin]$ java -version java version &q ...