zoukankan      html  css  js  c++  java
  • SQL in与exists的执行效率比较

    SQL中in可以分为三类:

        形如select * from t1 where f1 in ('a','b'),应该和以下两种比较效率:select * from t1 where f1='a' or f1='b' 或者 select * from t1 where f1 ='a' union all select * from t1 f1='b',你可能指的不是这一类,这里不做讨论。
        形如select * from t1 where f1 in (select f1 from t2 where t2.fx='x'),其中子查询的where里的条件不受外层查询的影响,这类查询一般情况下,自动优化会转成exist语句,也就是效率和exist一样。
        形如select * from t1 where f1 in (select f1 from t2 where t2.fx=t1.fx),其中子查询的where里的条件受外层查询的影响,这类查询的效率要看相关条件涉及的字段的索引情况和数据量多少,一般认为效率不如exists。除了第一类in语句都是可以转化成exists 语句的SQL,一般编程习惯应该是用exists而不用in,而很少去考虑in和exists的执行效率。

    A,B两个表

        当只显示一个表的数据如A,关系条件只一个如ID时,使用IN更快:select * from A where id in (select id from B)
        当只显示一个表的数据如A,关系条件不只一个如ID,col1时,使用IN就不方便了,可以使用EXISTS:select * from A where exists (select 1 from B where id = A.id and col1 = A.col1)
        当只显示两个表的数据时,使用IN,EXISTS都不合适,要使用连接:select * from A left join B on id = A.id

    所以使用何种方式,要根据要求来定。

    这是一般情况下做的测试:
    1    set statistics io on
    2    select * from sysobjects where exists (select 1 from syscolumns where id=syscolumns.id)
    3    select * from sysobjects where id in (select id from syscolumns )
    4    set statistics io off
    1    (47 行受影响)
    2    表'syscolpars'。扫描计数 1,逻辑读取 3 次,物理读取 0 次,预读 2 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
    3    表'sysschobjs'。扫描计数 1,逻辑读取 3 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
    4    (1 行受影响)
    1    (44 行受影响)
    2    表'syscolpars'。扫描计数 47,逻辑读取 97 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
    3    表'sysschobjs'。扫描计数 1,逻辑读取 3 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
    4    (1 行受影响)
    1    set statistics io on
    2    select * from syscolumns where exists (select 1 from sysobjects where id=syscolumns.id)
    3    select * from syscolumns where id in (select id from sysobjects )
    4    set statistics io off
    1    (419 行受影响)
    2    表'syscolpars'。扫描计数 1,逻辑读取 10 次,物理读取 0 次,预读 15 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
    3    表'sysschobjs'。扫描计数 1,逻辑读取 3 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
    4    (1 行受影响)
    1    (419 行受影响)
    2    表'syscolpars'。扫描计数 1,逻辑读取 10 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
    3    表'sysschobjs'。扫描计数 1,逻辑读取 3 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
    4    (1 行受影响)

    测试结果(总体来讲exists比in的效率高):

    效率:条件因素的索引是非常关键的

    把syscolumns 作为条件:syscolumns 数据大于sysobjects

    用in 扫描计数 47,逻辑读取 97 次,用exists 扫描计数 1,逻辑读取 3 次。把sysobjects作为条件:sysobjects 的数据少于 syscolumns,exists 比 in 多预读 15 次。

    如果要查询每个类别的最大sid 的话
    1    select * from test a
    2      where not exists(select 1 from test where sort = a.sort and sid > a.sid)


    1    select * from test a
    2      where sid in (select max(sid) from test where sort = a.sort)

    的执行效率要高三倍以上。

    sql优化中,使用in和exist? 主要是看你的筛选条件是在主查询上还是在子查询上。

  • 相关阅读:
    android flash air 打包工具
    MyEclipse 7.0快捷键大全
    android mp4 videoView
    位图处理
    myeclise10.0下载
    dropdown.js
    back track
    ANE 跨平台 as3 转 objectc android desktop
    jquery 例子
    android 屏蔽 home 2
  • 原文地址:https://www.cnblogs.com/AllUserBegin/p/3513084.html
Copyright © 2011-2022 走看看