MySQL中比较in和exists的区别

 

目录

前言

结论

in查询分析

EXISTS查询分析


 

前言

 

本文转载自https://blog.csdn.net/weixin_39539399/article/details/80851817

 

 

结论

 

exists和in都用于两个表的连接查询中,最好遵循小表驱动大表的原则

exists适合B表比A表数据大的情况,in适合A表比B表数据大的情况

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

 

 

in查询分析

 

SELECT
	* 
FROM
	A 
WHERE
	id IN ( SELECT id FROM B );

 这条SQL等价于

1. SELECT id FROM B 

2. SELECT * FROM A WHERE A.id = B.id   

 

解析

上面的SQL中先执行in后面的查询,in后面的查询只执行了一次,它查询出B表中所有的id并缓存,然后检查A表中的id在缓存中是否存在,如果存在则将A的查询数据加入到结果集中,直到遍历完A表中的所有结果未知

 

性能分析

public class testIN {
	public static void main(String[] args){
		List result = new ArrayList();	//定义结果集存储A
		String A[] = {"SELECT * FROM A"};	//定义数组A存储从A表查询到的结果集
		String B[] = {"SELECT id FROM B"};	//定义数组B存储从B表查询到的结果集
		for(int i=0;i<A.length;i++){
			for(int j=0;j<B.length;j++){
				result.add(A);
				break;
			}
		}
	}
}

通过上面的程序可以看出,当B表数据较大时,in操作会让B表中的数据全部遍历一遍,因此B表数据较大时使用in查询效率很低

当A表中有100条记录,B表中有1000条记录,那么最多可能遍历1000次,效率很差

当A表中有1000条记录,B表中有100条记录,最多遍历100次,内循环次数减少,效率大大提升。

 

结论:IN()查询时候B表数据比A表数据小的情况,IN()查询是从缓存中取数据

 

 

EXISTS查询分析

 

SELECT
	* 
FROM
	A 
WHERE
	EXISTS ( SELECT 1 FROM B WHERE B.id = A.id );

这条SQL等价于

1.SELECT * FROM A;

2.SELECT 1 FROM B WHERE B.id = A.id;

 

解析

EXISTS查询会先执行SELECT * FROM A查询,执行A.length次,并且不会将先执行的查询结果进行缓存,因为EXIST查询返回的是一个布尔值,它只在乎EXISTS的查询中是否有记录,与具体的结果集无关。

EXISTS查询将主查询的结果集放到子查询中做验证,根据验证结果是true或false决定主查询的数据结果是否得以保存。

 

性能分析

public class testEXISTS {
	public static void main(String[] args){
		List result = new ArrayList();	//定义结果集存储A
		String A[] = {"SELECT * FROM A"};	//定义数组A存储从A表查询到的结果集
	
		for(int i=0;i<A.length;i++){
			if(exists(A[i].id)){ //执行select 1 from B where B.id=a.id是否有记录返回
				result.add(A);
			}
		}
	}
}

通过上面的程序可以看出,当B表的数据比A表的数据大时适合使用EXISTS查询,因为它不用遍历B操作,只执行一次查询即可

当A表有100条记录,B表有1000条记录,那么EXISTS会执行100次去判断A表中的id是否与B表中的id相等,因为它只执行A.length次,可见B表的数据越多,越适合EXISTS发挥效果

当A表有10000条记录,B表有100条记录,那么EXISTS还是会执行10000次,此时不如使用in遍历100次效率高。因为IN是在内存中遍历比较,而EXISTS需要查询数据库。查询数据库消耗的性能更多,效率更低。

 

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值