建议少用 in 和not in,在SQL里面,开销比较大

解决方案 »

  1.   

    或许把'xxx'放入一个临时表中,再改进查询会好一些。
      

  2.   

    bm的索引已经建了,改善不大,服务器的超时选项我倒是用默认的.我每次查询只能bm in('xxxx',.......)括号里12个bm,超过12个就不行.
      

  3.   

    你用EXISTS 和NOT WXISTS看看
    select * from tablename where bm EXISTS ('1011','1533','1535',......) order by bm
      

  4.   

    楼上用EXISTS是不正确的:
    select * from tablename where bm EXISTS ('1011','1533','1535',......) order by bm
    建议其去看看相关的资料楼主的这个问题也可以用union进行连接查询
      

  5.   

    select * from tablename a left join (select '1011' bm union all select '1533' bm union all select '1535' bm union all select ......) b 
    on a.bm=b.bm  where b.bm is null order by bm
      

  6.   

    不对.改一下
    select * from tablename a left join (select '1011' bm union all select '1533' bm union all select '1535' bm union all select ......) b 
    on a.bm=b.bm  where b.bm is not null order by bm
      

  7.   

    建一临时表,把数据插入到临时表中,然后select * from tablename A, 临时表 B 
     where A.bm = B.bm
    order by A.bm 即可
      

  8.   

    用union也不好,客户给的bm值不固定且很多,这样的查询语句太长了,不理想.
      

  9.   

    select * from tablename where bm in('1011','1533','1535',......) order by bm
    就这样了.超时可能要在其它方面找原因.如:索引建立是否合理? 数据表是否频繁修改删除而索引长期没维护过.
       真正的语句是不是这样?
       表是否过于宠大?有没有分表或建分区视图的必要?
       还有是不是语句查询时间本身不是很长,而你超时设置却很短.
      

  10.   

    //用union也不好,客户给的bm值不固定且很多,这样的查询语句太长了,不理想.你先把轉來的字符串數據放到一個臨時表中,臨時表中有兩個字段id,bmcreate table #t(id int idnetity(1,1),bm varchar(10))然後寫個涵數把轉來的字符串插入到這個臨時表中,在查詢數據 的時候通過與這個臨時表關聯從而取得bm我想這樣做可能會快點
      

  11.   

    我同意用EXISTS 和NOT WXISTS看看
      

  12.   

    首先要说明一下,这种要求用EXISTS 和NOT EXIST跟本不行的.语句不符合要求!select * from TableName where bm in (......)
    按你的要求,这是最基础的T-SQL语句.很难有什么比它更快的了.
    如果客户字符串实在太长,要在存储过程中处理,也是要用表变量:declare @bm table (bm varchar(10) primary key)
    然后再联接.这也许快不了多少,或者还更慢.但你 用in (......)以经超时了,所以要在其它方面找原因.主要问题不在语句上.
      

  13.   

    谢谢大家,具体sql语句是这样的:
    SELECT YPBM=NR.BM, YPMC=NR.MC, NR.BZ, NR.GG,SF.YS,NR.DW,NR.BZS,NR.BZDW, 
                   DJ=CASE WHEN ZY.BM IS NULL THEN CF.DJ ELSE ZY.DJ END, 
                   SL=CASE WHEN ZY.BM IS NULL THEN CF.ZL ELSE CF.ZL * ZY.YL END, 
                   JE=CASE WHEN ZY.BM IS NULL THEN CF.FY ELSE CF.ZL * ZY.FY END  
                   INTO #TMP 
                    FROM mz_sf200411 SF,mz_cf200411 CF 
                    LEFT JOIN MZ_ZYCF ZY ON CF.CFID=ZY.CFID, ZD_MZCFNR NR 
                    WHERE SF.SFID=CF.SFID AND SF.STATE & 0x85=0x04
                    AND NR.BM=CASE WHEN ZY.BM IS NULL THEN CF.BM ELSE ZY.BM END 
                   AND CASE WHEN ZY.BM IS NULL THEN CF.LX ELSE 3 END IN (0,4) 
                   AND NR.JB & 511>0x00 AND NR.JX IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50)            
             AND SF.SFRQ>=(DATEDIFF(DAY, '1899-12-30','2004-11-01')) 
             and SF.SFRQ<=(DATEDIFF(DAY, '1899-12-30','2004-11-30')) 
             AND NR.BM IN('3534','4554','3443','1244',......)   --关键是这里,只能装12个数
    go 
    SELECT B.MC '医生姓名',A.YPBM '药品编码', A.YPMC '药品名称', A.BZ '包装', A.GG '规格', A.DJ '单价', 
                  消耗量1=ltrim(str(SUM(A.SL),len(str(SUM(A.SL))),2))+A.DW, 消耗量2=ltrim(str(sum(A.SL)/A.BZS, 
                  len(str(sum(A.SL)/A.BZS)),2))+A.BZDW,金额=SUM(A.JE) 
                  FROM #TMP A,ZD_RY B 
                  WHERE A.YS=B.BM 
                  GROUP BY A.YPBM, A.YPMC, A.BZ, A.GG,A.DJ,B.MC,A.DW,A.BZS,A.BZDW 
                  ORDER BY A.YPBM 
      

  14.   

    你先把轉來的字符串數據放到一個臨時表中,臨時表中有兩個字段id,bmcreate table #t(id int idnetity(1,1),bm varchar(10))
    ////////////////////////////////////////////////////
    这个方法好!性能提高好多。