table表里的数据应该没有限制吧

解决方案 »

  1.   

    建议:当table 的记录很多时,将IN(select id form table)
    改写成exists(select....)的形式,这样效率更高点!
      

  2.   

    --当然,楼主这样的语句效率是很差的,建议改用join,类似这样:select a.* 
    from 表 a join(
     select id form table
    )b on a.id=b.id
      

  3.   

    谢谢 welyngj,我也查了好久,没看到这样的资料,不过没确切的资料总有点不太放心
    谢谢 shuiniu,exists为什么会比in有效率呢?
      

  4.   

    这是因为EXISTS在查询的时候,只要找到符合的条件就返回!而不是像IN一样,查询整个表,所以EXISTS效率高撒
      

  5.   

    in的执行是这样的,举个例子:
    select count(*) from stuff where id_no in('0','1')
    对于上而这句,where条件中的'in'在逻辑上相当于'or',所以语法分析器会将in ('0','1')转化为id_no ='0' or id_no='1'来执行。我们期望它会根据每个or子句分别查找,再将结果
    相加,但实际上(根据showplan),它却采用了"OR策略",即先取出满足每个or子句的行,存入临时数据库的工作表中,再建立唯一索引以去掉重复行,因此,表扫描的次数是很多次的exists 是返回标志true(扫描到满足条件的记录),或返回false,而不需要完整搜索整个表,也不需要返回结果集,所有比in有效率,但它也要多次扫描表,进行判断用join的话,则只扫描一次table,再与第一个表做联合筛选所以理论上来说,三种方法的效率由低到高是:in exists join
      

  6.   

    用in(select id form table)的时候,系统要扫描整个table,而用exists则不需要
    扫描整个表,发现记录符合条件即跳出子查询!
      

  7.   

    用Exists当然好,可能不能保证查询出来的数据是所有符合条件的数据呢。
      

  8.   

    谢谢zjcxc:那么sql service允许一个查询里有几个or的关系呢,如
    select * from id=1 or id=2 or id=3 or ......id=n
    这个n可以有多大呢,无限大肯定不可能吧,那么他是由什么限定呢
      

  9.   

    这个n在理论上是无限大的(只要你的机器配置足够处理)不过包含 SQL 语句的字符串长度(批处理大小)的上限是:65,536 * 网络数据包大小
    络数据包大小是表格格式数据方案 (TDS) 数据包的大小,该数据包用于应用程序和关系数据库引擎之间的通讯。默认的数据包大小为 4 KB,由 network packet size 配置选项控制。
      

  10.   

    再次谢谢zjcxc(邹建):
    上面的 65,536 * 网络数据包大小 这个公式中,为什么要语句的长度*数据包的大小呢
    我的理解是一个sql语句只有65536的长度,如果in子句大于65536那就应该出错了,或者大于数据包的大小的时候也应该出错,为什么是两个的乘积呢???
      

  11.   

    在这里冒昧的问一句:ansi sql好象有关于in里的子项长度规定,各位大大有没有看到类似的文章呢,还请相告??
      

  12.   

    SQL联机帮助上是这样写的,我理解的意思是:一个SQL语句,最多可以分成65536个数据包发送,而每个数据包的默认为4K,所以是65536*网络数据包大小
      

  13.   

    谢谢邹建:
    我刚才用下面的程序测试了一下(c#),结果发现n=3000时就出错了(n=2000时还是对的)。
    还有没有可能别的东西约束了它的长度?????
    -----------------------------------------
    string s="";
    int n=0;
    n=Convert.ToInt32(textBox1.Text);
    for(int i=0;i<n;i++){s+=(i+",");}
    s+="0";
    string strConnection="连接字符串";
    SqlConnection conn=new SqlConnection(strConnection);
    string sql="select * from students where studentid in("+s+")";
    DataSet ds=new DataSet();
    try
    {
       SqlDataAdapter adapter=new SqlDataAdapter(sql,conn);
       adapter.Fill(ds);
       MessageBox.Show("ok!!");
    }
    catch
    {
      MessageBox.Show("错了!!");
    }
      

  14.   

    --出现什么错误提示? 应该是你的程序不支持这么长的字符串吧?--下面是我在查询分析器中的测试,每个字符串包含1500个数字,共计4500个数字,测试通过declare @s1 varchar(8000),@s2 varchar(8000),@s3 varchar(8000),@i int
    select @s1='',@s2='',@s3='',@i=0
    while @i<1500
    select @s1=@s1+','+cast(@i as varchar)
    ,@s2=@s2+','+cast(@i+1500 as varchar)
    ,@s3=@s3+','+cast(@i+3000 as varchar)
    ,@i=@i+1
    set @s1=substring(@s1,2,8000)
    exec('select name from sysobjects where id in('+@s1+@s2+@s3+')')
      

  15.   

    sorry,刚才我在查询分析器里试试了一下,3000项可以运行
    可能是超时的原因,但是我在数据库连接里已经设置为没有时限了,上面的程序到底哪有问题>????
      

  16.   

    这种带有in 的相关查询条件在sql查询命令中只能使用一次。。
    如果想要查找多个相关的子查询的话,应该用exist命令