mysql exists 和 in的效率比较

这条语句适用于a表比b表大的情况

select * from ecs_goods a where cat_id in(select cat_id from ecs_category);

这条语句适用于b表比a表大的情况
select * from ecs_goods a where EXISTS(select cat_id from ecs_category b where a.cat_id = b.cat_id);

原因:(转发)

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

以上查询使用了in语句,in()只执行一次,它查出B表中的所有id字段并缓存起来.之后,检查A表的id是否与B表中的id相等,如果相等则将A表的记录加入结果集中,直到遍历完A表的所有记录.
它的查询过程类似于以下过程

List resultSet=[];
Array A=(select * from A);
Array B=(select id from B);

for(int i=0;i<A.length;i++) {
   for(int j=0;j<B.length;j++) {
      if(A[i].id==B[j].id) {
         resultSet.add(A[i]);
         break;
      }
   }
}
return resultSet;

可以看出,当B表数据较大时不适合使用in(),因为它会B表数据全部遍历一次.
如:A表有10000条记录,B表有1000000条记录,那么最多有可能遍历10000*1000000次,效率很差.
再如:A表有10000条记录,B表有100条记录,那么最多有可能遍历10000*100次,遍历次数大大减少,效率大大提升.

结论:in()适合B表比A表数据小的情况

select a.* from A a 
where exists(select 1 from B b where a.id=b.id)

以上查询使用了exists语句,exists()会执行A.length次,它并不缓存exists()结果集,因为exists()结果集的内容并不重要,重要的是结果集中是否有记录,如果有则返回true,没有则返回false.
它的查询过程类似于以下过程

List resultSet=[];
Array A=(select * from A)

for(int i=0;i<A.length;i++) {
   if(exists(A[i].id) {    //执行select 1 from B b where b.id=a.id是否有记录返回
       resultSet.add(A[i]);
   }
}
return resultSet;

当B表比A表数据大时适合使用exists(),因为它没有那么遍历操作,只需要再执行一次查询就行.
如:A表有10000条记录,B表有1000000条记录,那么exists()会执行10000次去判断A表中的id是否与B表中的id相等.
如:A表有10000条记录,B表有100000000条记录,那么exists()还是执行10000次,因为它只执行A.length次,可见B表数据越多,越适合exists()发挥效果.
再如:A表有10000条记录,B表有100条记录,那么exists()还是执行10000次,还不如使用in()遍历10000*100次,因为in()是在内存里遍历比较,而exists()需要查询数据库,我们都知道查询数据库所消耗的性能更高,而内存比较很快.

结论:exists()适合B表比A表数据大的情况

当A表数据与B表数据一样大时,in与exists效率差不多,可任选一个使用.

时间: 2024-12-18 08:06:08

mysql exists 和 in的效率比较的相关文章

[MySQL优化] -- 如何查找SQL效率地下的原因

[MySQL优化] -- 如何查找SQL效率地下的原因   来源: ChinaUnix博客 日期: 2009.07.20 16:12 (共有条评论) 我要评论       查询到效率低的 SQL 语句 后,可以通过 EXPLAIN 或者 DESC 命令获取 MySQL 如何执行 SELECT 语句的信息,包括在 SELECT 语句执行过程中表如何连接和连接的顺序,比如我们想计算 2006 年所有公司的销售额,需要关联 sales 表和 company 表,并且对 profit 字段做求和( su

mysql 有报错  ERROR! MySQL is not running, but lock file (/var/lock/subsys/mysql) exists

sh-4.1# /etc/init.d/mysqld status ERROR! MySQL is not running, but lock file (/var/lock/subsys/mysql) exists sh-4.1# /etc/init.d/mysqld start Starting MySQL. ERROR! The server quit without updating PID file (/data1/mysql/mysql.pid). sh-4.1# rm mysql

MySQL多表关联查询效率高点还是多次单表查询效率高,为什么?

MySQL多表关联查询效率高点还是多次单表查询效率高,为什么? <阿里巴巴JAVA开发手册>里面写超过三张表禁止join 这是为什么?这样的话那sql要怎么写? 原文地址:https://www.cnblogs.com/gotodsp/p/10090382.html

mysql中IN和EXITS效率

mysql中的in语句是把外表和内表作hash 连接,而exists语句是对外表作loop循环,每次loop循环再对内表进行查询.一直大家都认为exists比in语句的效率要高,这种说法其实是不准确的.这个是要区分环境的. 如果查询的两个表大小相当,那么用in和exists差别不大. 如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in: 例如:表A(小表),表B(大表) 1: select * from A where cc in (select cc from

mysql exists 如何使用

还没时间看,exists用的少  ==>当你只需要判断后面的查询结果是否存 在时使用exists() http://edu.codepub.com/2011/0208/29218.php 今天正好做一个查询,两个表中过滤数据,当T1中字段F1在T2表的F2中存在时,返回这条件数据.刚刚开始觉得简单,就想到子查询和连接查询,但是发现 两个表中如果数据量多时,这样就不行,并且效率不高,后来想到用Mysql中的In函数 今天正好做一个查询,两个表中过滤数据,当T1中字段F1在T2表的F2中存在时,返回

mysql exists用法

在mysql中,有个关键字exists比较难理解,今天就来搞明白其含义和应用 exists的使用总是跟子查询关联起来,一种是不相关子查询,对于exists来说更常用的是相关子查询 不相关子查询:子查询和父查询没有直接的关系.只要子查询为真,则返回父查询的所有结果.否则返回空 select A.id from A where exists (select B.name from B where B.name = "hello world"); 相关子查询: select A.id fro

oracle中的 exists 和 in 的效率问题

1) select * from T1 where exists(select * from T2 where T1.a=T2.a) ; T1数据量小而T2数据量非常大时,T1<<T2 时,1) 的查询效率高. 2) select * from T1 where T1.a in (select T2.a from T2) ; T1数据量非常大而T2数据量小时,T1>>T2 时,2) 的查询效率高. in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次lo

mysql使用索引优化查询效率

索引的概念 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针.更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度.在没有索引的情况下,数据库会遍历全部数据后选择符合条件的:而有了相应的索引之后,数据库会直接在索引中查找符合条件的选项.如果我们把SQL语句换成"SELECT * FROM 表名 WHERE id=2000000",那么你是希望数据库按照顺序读取完200万行数据以后给你结果还是直接在索引中定位

SQL中in和exists的用法和效率区别

1. sql中in和exists的区别效率问题 2. SQL中IN和EXISTS用法的区别