IN 和 EXISTS 的区别及应用

IN 语句:只执行一次

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

    具体sql示例:oop

select * from student s where s.stuid in(select stuid from score ss where ss.stuid = s.stuid)


select * from student s where s.stuid in(select stuid from score ss where ss.stuid <1005)

以上两个语句的执行流程:性能

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

EXISTS语句:执行student.length次

指定一个子查询,检测行的存在。遍历循环外表,而后看外表中的记录有没有和内表的数据同样的。匹配上就将结果放入结果集中。spa

具体示例:code

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

这条sql语句的执行结果和上面的in的第一条执行结果是同样的。
可是,不同的是它们的执行流程彻底不同:索引

  使用exists关键字进行查询的时候,首先,咱们先查询的不是子查询的内容,而是查咱们的主查询的表,也就是说,咱们先执行的sql语句是:hash

select * from student s

 而后,根据表的每一条记录,执行如下语句,依次去判断where后面的条件是否成立:class

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进行处理。

select * from studnet where exists(select null)  等同于: select * from studnet

    in 是把外表和内表做hash 链接,而exists是对外表做loop循环,每次loop循环再对内表进行查询。一直以来认为exists比in效率高的说法是不许确的。

not in 和not exists     若是查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。因此不管那个表大,用not exists都比not in要快。

相关文章
相关标签/搜索