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的区别及使用场景的更多相关文章

  1. MySQL中Exists和In的使用

    Exists关键字: exists表示存在,是对外表做loop循环,每次loop循环再对内表(子查询)进行查询,那么因为对内表的查询使用的索引(内表效率高,故可用大表),而外表有多大都需要遍历,不可避 ...

  2. Mysql中EXISTS关键字用法、总结

    在做教务系统的时候,一个学生(alumni_info)有多个教育经历(alumni_education),使用的数据库是mysql,之前使用左链接查询的,发现数据量才只有几万条时,查询就很慢了,早上想 ...

  3. MySQL 中 EXISTS 的用法

    在MySQL中 EXISTS 和 IN 的用法有什么关系和区别呢? 假定数据库中有两个表 分别为 表 a 和表 b create table a ( a_id int, a_name varchar( ...

  4. 关于MySQL 中 EXISTS 的用法

    在MySQL中 EXISTS 和 IN 的用法有什么关系和区别呢? 假定数据库中有两个表 分别为 表 a 和表 b create table a ( a_id int, a_name varchar( ...

  5. 用count(*)还是count(列名) || Mysql中的count()与sum()区别

    Mysql中的count()与sum()区别   首先创建个表说明问题 CREATE TABLE `result` (   `name` varchar(20) default NULL,   `su ...

  6. MySQL中interactive_timeout和wait_timeout的区别【转】

    在用mysql客户端对数据库进行操作时,打开终端窗口,如果一段时间没有操作,再次操作时,常常会报如下错误: ERROR 2013 (HY000): Lost connection to MySQL s ...

  7. Mysql中函数和存储过程的区别

    Mysql中函数和存储过程的区别 存储过程: 1.       可以写sql语句 2.       inout,out构造返回值 3.       调用:call:存储过程名称 4.       可以 ...

  8. MySQL中 utf8与utf8mb4的区别

    MySQL中 utf8与utf8mb4的区别 一.简介 ​ MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode.好在 ...

  9. 浅析MySQL中exists与in的使用

    exists对外表用loop逐条查询,每次查询都会查看exists的条件语句,当 exists里的条件语句能够返回记录行时(无论记录行是的多少,只要能返回),条件就为真,返回当前loop到的这条记录, ...

随机推荐

  1. day10.函数升级

    1.写函数,接受n个数字,求这些参数数字的和.(动态传参) def summ(*args): all = 0 for i in args: all = all + i return all ret = ...

  2. net core体系-API-1Ocelot-(2)继续深入

    简单的说Ocelot是一个用.NET Core实现并且开源的API网关技术.可能你又要问了,什么是API网关技术呢?Ocelot又有什么特别呢?我们又该如何集成到我们的asp.net core程序中呢 ...

  3. UOJ#351. 新年的叶子 概率期望

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ351.html 题目传送门 - UOJ351 题意 有一个 n 个节点的树,每次涂黑一个叶子节点(度为 1 ...

  4. Badboy录制Jmter脚本

    提纲 1.特性和用途 2.下载和安装 3.界面介绍 4.录制脚本(注意:badboy默认是打开就开始录制,需要在step双击后进行取消默认设置) 5.添加断言(参数化设置,注意:badboy默认只运行 ...

  5. 怎样将一个Long类型的数据转换成字节数组

    直接上代码: //先写进去 long n = 1000000L; ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutpu ...

  6. HDU-1170的解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1170 题意:要求输入几个案例,每个案例包含操作符(+,-,*,/),操作数(两个整数).现在要求分别输 ...

  7. Go版GTK:环境搭建(windows)

    Go版GTK:环境搭建(windows) https://blog.csdn.net/tennysonsky/article/details/79221507 所属专栏: Go语言开发实战     1 ...

  8. 使用PHPStorm 配置自定义的Apache与PHP环境

    使用PHPStorm 配置自定义的Apache与PHP环境之一   关于phpstorm配置php开发环境,大多数资料都是直接推荐安装wapmserver.而对于如何配置自定义的PHP环境和Apach ...

  9. 现在没有可用的软件包 *** ,但是它被其它的软件包引用了 和 E: 无法定位软件包 ***问题解决(思路清晰干货)

    问题现象 root@zhouls-virtual-machine:~/snort_src# apt-get install bison flex 正在读取软件包列表... 完成 正在分析软件包的依赖关 ...

  10. javascipt

    JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEase.(客户端执行的语言) Net ...