MySQL in和exists查询对比

sql实例

外表:tableA
内表:tableB
INselect * from tableA where tableA.id IN ( select A_Id from tableB )
EXISTSselect * from tableA where EXISTS ( select * from tableB where tableB.A_Id = tableA.id )

执行原理

in的执行原理,是把外表和内表做hash连接,主要用到外表索引
exists的执行原理,是对外表做loop循环,主要用到内表索引

In 和 Exists 分析

以下部分主要引用自https://blog.csdn.net/kk123k/article/details/80614956,稍作改动,如有侵权,烦请联系我删除

In 查询

第1条查询其实就相当于or语句,假设B表有A_Id分别为id1,id2 … idN这N条记录,那么上面语句可以等价转化成:

select * from tableA where tableA.id = id1 or tableA.id = id2 or ... or tableA.id = idN;

主要是用到了A表的索引,B表的大小对查询效率影响不大

Exists 查询

第2条查询,可以理解为类似下列流程

function GetExists () {
	var resultSet = []
	for(var i = 0; i< ResultA.length; i++){
		//从tableA逐条获取记录
		var dataA = getId(tableA, i)
		if(tableB.A_Id === dataA.id){
			result.push(dataA)
		}
	}
	return resultSet
}

主要是用到了B表的索引,A表大小对查询效率影响不大

Not In 和 Not Exists 分析

select * from tableA where tableA.id NOT IN ( select A_Id from tableB )
select * from tableA where not exists ( select * from tableB where tableB.A_Id = tableA.id )
Not In 查询

类似,第1条查询相当于and语句,假设B表有A_Id分别为id1,id2 … idN这N条记录,那么上面语句可以等价转化成:

select * from tableA where tableA.id != id1 and tableA.id != id2 and ... and tableA.id != idN

not in是个范围查询,由于! =不能使用任何索引,故A表的每条记录,都要在B表里遍历一次,查看B表里是否存在这条记录,而not exists还是和上面一样,用了B的索引,所以无论什么情况,not exists都比not in效率高

总结:
如果查询的两个表大小相当,那么用in和exists效率差别不大

如果两个表中一个较小,一个较大,则子查询表大的用exists,子查询表小的用in。
例如:有表A (表)和表B(表)

1:

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列的索引。
2:
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要快

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值