Sql 语句中 IN 和 EXISTS 的区别及应用

Sql 语句中 IN 和 EXISTS 的区别及应用

IN 语句:只执行一次

确定给定的值是否与子查询或列表中的值相匹配。in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。所以相对内表比较小的时候,in的速度较快。

具体sql示例:

//相关子查询
1select * from student stu where stu.stuid in(select stuid from score s where s.stuid = stu.stuid)
//不相关子查询
2select * from student stu where stu.stuid in(select stuid from score s where s.stuid <1005)

以上两个语句的执行流程:
首先会执行from语句找出student表,然后执行 in 里面的子查询,再然后将查询到的结果和原有的user表做一个笛卡尔积,再根据我们的student.stuid IN score.stuid的条件,将结果进行筛选(既比较stuid列的值是否相等,将不相等的删除)。最后,得到符合条件的数据。

EXISTS语句:执行student.length次

具体示例:

select * from student stu where EXISTS(select stuid from score s where s.stuid = stu.stuid)

这条sql语句的执行结果和上面的in的第一条执行结果是一样的。
但是,不一样的是它们的执行流程完全不一样:
  使用exists关键字进行查询的时候,首先,我们先查询的不是子查询的内容,而是查我们的主查询的表,也就是说,我们先执行的sql语句是:

select * from student stu

然后,根据查询出来的每一条记录,执行以下语句,依次去判断where后面的条件是否成立:

EXISTS(select stuid from score ss where ss.stuid = s.stuid)

如果成立则返回true不成立则返回false。如果返回的是true的话,则该行结果保留,如果返回的是false的话,则删除该行,最后将得到的结果返回。

区别及应用场景

in 和 exists:
  如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用in, 反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists。
  其实我们区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询,所以我们会以驱动表的快速返回为目标,那么就会考虑到索引及结果集的关系了 ,另外IN时不对NULL进行处理
  in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。一直以来认为exists比in效率高的说法是不准确的。
  
not in 和 not exists:
  如果查询语句使用了not in,那么内外表都进行全表扫描,没有用到索引;而not exists 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快
  
SQL语句执行顺序可参考:https://blog.csdn.net/wqc19920906/article/details/79411854

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值