zoukankan      html  css  js  c++  java
  • SQL in与exists相关性能问题总结

    SQL  in与exists相关性能问题总结

    • in 和 exists     

         in 和 exists的是DBA或开发人员日常工作学习中常用的基本运算符,今天我就这两个所带来的性能问题进行分析总结,方便自己与他人的后续学习与工作。

        先来了解in 和 exists的性能区别: 如果主查询中的表较大且又有索引,子查询得出的结果集记录较少时,应该用in;反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists。

    举例说明: select * from A where A.ID in(select B.ID from B )

                      select * from A  where exists(select 1 from B where A.ID=B.ID)

      其中,第一句in字句使用的是外层A表的索引,括号中的B全表扫描,所以,当A表巨大而B表很小的时候,此时性能较高,反之性能很差;

                    第二句exists字句中使用的是内层B表的索引,外面A全表扫描,所以,当B表巨大而A表很小的时候,此时性能较高,反之性能很差。

         区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是in,那么先执行子查询,再以in为驱动表,去查找外层表中符合要求的记录,所以我们会以驱动表的快速返回为目标,那么就会考虑到索引及结果集的关系了。

    a)         in的执行顺序:

    1.首先执行一次子查询,子查询先产生结果集;

    2. 然后主查询再去结果集里去找符合要求的字段列表去.符合要求的输出,反之则不输出。

    b)        exists的执行顺序:

    1.首先执行一次外部查询;

    2.对于外部查询中的每一行分别执行一次子查询,而且每次执行子查询时都会引用外部查询中当前行的值;

    3.使用子查询的结果true或false来确定外部查询的结果集。

    例如:表A(小表),表B(大表)
    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列的索引。
    相反的:
    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列的索引。

    exists适合外表结果集很小的情况;in适合外表结果集很大,而内表结果集较小的情况。

    •  not in 和not exists

         这里首先要说,not in 逻辑上不完全等同于not exists,当子查询中返回的任意一条记录含有空值,则not in查询将不返回任何记录;当子查询字段有非空限制,这时可以使用not in。

    1、对于not exists查询,内表存在空值对查询结果没有影响;对于not in查询,内表存在空值将导致最终的查询结果为空。

    2、对于not exists查询,外表存在空值,存在空值的那条记录最终会输出;对于not in查询,外表存在空值,存在空值的那条记录最终将被过滤,其他数据不受影响。

    3、解释为什么not in语句比not exists语句效率差这么多(not in 不走索引):

         not exists语句很显然就是一个简单的两表关联,内表与外表中存在空值本身就不参与关联;

         not exists的执行顺序是:在表中查询,是根据索引查询的,如果存在就返回true,如果不存在就返回false,不会每条记录都去查询。

         not in的执行顺序是:是在表中一条记录一条记录的查询(查询每条记录)符合要求的就返回结果集,不符合的就继续查询下一条记录,直到把表中的记录查询完。也就是说为了证明找不到,所以只能查询全部记录才能证明,并没有用到索

     

     

     

  • 相关阅读:
    中国一些web service收藏
    DataSet 和 List<T> 相互 转换
    JS图表
    IIS DirectoryEntry
    JS弹框
    Remoting
    Del SVN Configuare File BAT
    Viewport3D对象转换成图片
    在WPF中进行碰撞检测
    Button自定义样式
  • 原文地址:https://www.cnblogs.com/syforacle/p/5820624.html
Copyright © 2011-2022 走看看