MySQL中exists和in的区别及使用场景
exists和in的使用方式:
|
1
|
#对B查询涉及id,使用索引,故B表效率高,可用大表 -->外小内大 |
|
1
|
select * from A where exists (select * from B where A.id=B.id); |
|
1
|
#对A查询涉及id,使用索引,故A表效率高,可用大表 -->外大内小 |
|
1
|
select * from A where A.id in (select id from B); |
1、exists是对外表做loop循环,每次loop循环再对内表(子查询)进行查询,那么因为对内表的查询使用的索引(内表效率高,故可用大表),而外表有多大都需要遍历,不可避免(尽量用小表),故内表大的使用exists,可加快效率;
2、in是把外表和内表做hash连接,先查询内表,再把内表结果与外表匹配,对外表使用索引(外表效率高,可用大表),而内表多大都需要查询,不可避免,故外表大的使用in,可加快效率。
3、如果用not in ,则是内外表都全表扫描,无索引,效率低,可考虑使用not exists,也可使用A left join B on A.id=B.id where B.id is null 进行优化。
此外,新近遇到的坑,mysql版本问题:
MySQL版本问题:5.6.5优化了子查询,引入物化子查询(针对where clause的subquery),子查询物化将子查询结果存入临时表,确保子查询只执行一次,该表不记录重复数据且采用哈希索引查找;
而之前的版本则会把非相关子查询转化为相关子查询,导致效率低下(尤其是子查询是小表,外表是大表的情况下,效率变慢许多)。
相关子查询:子查询依赖外层连接的返回值;
非相关子查询:子查询不依赖外层连接的返回值;
子查询分两种,from语句(派生表)和where语句(子查询),派生表的效率要高一些,5.6的优化就是把where语句变成from语句。
本来是内表小,用的in,但是据说5.6之前的版本会把非相关子查询改为相关子查询,就是把in的语句改成了exists的,结果效率超低。
实验说明:派生表join比派生表的速度还要快。而使用in查询需要很多分钟还没有查出来。

#使用派生表 4.68秒
SELECT id FROM la WHERE cardid IN (
SELECT cardid FROM (
select cardid from la group by cardid having count(1)>50) a) ;
#使用派生表的内连接 1.26秒
SELECT id FROM la JOIN (
select cardid from la group by cardid having count(1)>50) a ON la.cardid=a.cardid;

MySQL中exists和in的区别及使用场景的更多相关文章
- MySQL中Exists和In的使用
Exists关键字: exists表示存在,是对外表做loop循环,每次loop循环再对内表(子查询)进行查询,那么因为对内表的查询使用的索引(内表效率高,故可用大表),而外表有多大都需要遍历,不可避 ...
- Mysql中EXISTS关键字用法、总结
在做教务系统的时候,一个学生(alumni_info)有多个教育经历(alumni_education),使用的数据库是mysql,之前使用左链接查询的,发现数据量才只有几万条时,查询就很慢了,早上想 ...
- MySQL 中 EXISTS 的用法
在MySQL中 EXISTS 和 IN 的用法有什么关系和区别呢? 假定数据库中有两个表 分别为 表 a 和表 b create table a ( a_id int, a_name varchar( ...
- 关于MySQL 中 EXISTS 的用法
在MySQL中 EXISTS 和 IN 的用法有什么关系和区别呢? 假定数据库中有两个表 分别为 表 a 和表 b create table a ( a_id int, a_name varchar( ...
- 用count(*)还是count(列名) || Mysql中的count()与sum()区别
Mysql中的count()与sum()区别 首先创建个表说明问题 CREATE TABLE `result` ( `name` varchar(20) default NULL, `su ...
- MySQL中interactive_timeout和wait_timeout的区别【转】
在用mysql客户端对数据库进行操作时,打开终端窗口,如果一段时间没有操作,再次操作时,常常会报如下错误: ERROR 2013 (HY000): Lost connection to MySQL s ...
- Mysql中函数和存储过程的区别
Mysql中函数和存储过程的区别 存储过程: 1. 可以写sql语句 2. inout,out构造返回值 3. 调用:call:存储过程名称 4. 可以 ...
- MySQL中 utf8与utf8mb4的区别
MySQL中 utf8与utf8mb4的区别 一.简介 MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode.好在 ...
- 浅析MySQL中exists与in的使用
exists对外表用loop逐条查询,每次查询都会查看exists的条件语句,当 exists里的条件语句能够返回记录行时(无论记录行是的多少,只要能返回),条件就为真,返回当前loop到的这条记录, ...
随机推荐
- 在grails中远程调用action
在进行类似批处理的程序时,如果在一个action中需要保存很多记录数,这会导致grails中的数据库session超过负荷,从而导致OOM. 因为这个情况的发生是由于在一次请求中,对数据进行的修改都保 ...
- IDEA创建Web项目(maven)
第一步:创建项目 第二步:使用maven创建,并选择jdk 第三步:修改项目名称 第四步:选择自动导入依赖(很重要!!) 第五步:添加核心依赖和打包 第六步:编译一下 第七步:配置web容器(这里是用 ...
- h5 rem js自动适配
(function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? ...
- 转 国内的go get问题的解决
转 国内的go get问题的解决 go get golang.org/x 包失败解决方法 由于各种问题,国内使用 go get 安装 golang 官方包可能会失败,如我自己在安装 colli ...
- php 图形用户界面GUI 开发
php 图形用户界面GUI 开发 一.下载指定系统扩展 1 2 http://pecl.php.net/package/ui http://pecl.php.net/package/ui/2.0.0/ ...
- LYOI 2016 Summer 函数 【线段树】
<题目链接> 题目大意: fqk 退役后开始补习文化课啦,于是他打开了数学必修一开始复习函数,他回想起了一次函数都是 f(x)=kx+b的形式,现在他给了你n个一次函数 fi(x)=kix ...
- sqlserver日志文件
过程: 昨天下午数据库奔溃,表现就是连不上数据库了,重启服务之后好了. 查询日文文件 , “Autogrow of file 'XX_log' in database 'XX' was cance ...
- python基础一 ------如何统计一个列表元素的频度
如何统计一个列表元素的频度 两个需求: 1,统计一个随机序列[1,2,3,4,5,6...]中的出现次数前三的元素及其次数 2,统计一片英文文章中出现次数前10 的单词 两种方法: 1,普通的for循 ...
- LeetCode之旅
14. 最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower",&quo ...
- CentOs中玩docker
1.启动: systemctl start docker.service 2.停止: systemctl stop docker 3.从usts上拉取仓库 编辑文件 vi /etc/docker/da ...