日期:2014-05-16  浏览次数:20472 次

SQL in (1,2,3.....)问题
表:Table
id:自动编号
ST:数字

表的记录大概有100万条左右

现在需要的是:
Select id From [Table] Where [id] in(1,2,3,4,5,................................) and [ST] = 0

但由于in()里面的数据太大,有上千条,导致出现以下错误问题:

查询处理器用尽了内部资源,无法生成查询计划。这种情况很少出现,只有在查询极其复杂或引用了大量表或分区时才会出现。

求解决思路?
------解决方案--------------------
动态拼接成 id=1 or id=2…………
------解决方案--------------------
几千个就直接生成一张表吧。 放到表里面 跟当前表 inner join 一下。

------解决方案--------------------
我试过上千个id之后是会出现这种情况,并且联机丛书上对in的解释中也有这样的说法,改成left join之类的才行
------解决方案--------------------
建议改为区间来查
Select id From [Table] Where  [ST] = 0 and ([id]>=1 and id <=5 or id>=100 and id<=10000) 
------解决方案--------------------
把数据存储在临时表然后用JOIN的办法,这么多IN会导致执行计划无法生成的。
------解决方案--------------------
Select id From [Table] Wherecharindex(id,'1,2,3……‘)>0 and [ST] = 0

这样呢?
------解决方案--------------------
因为in本质就是or,优化器对每个or都要做分析,过多的or会导致优化器无法分析,最后报错
------解决方案--------------------
引用:
因为in本质就是or,优化器对每个or都要做分析,过多的or会导致优化器无法分析,最后报错

我觉得不用那么麻烦把。
讨论下,这个可用?
Select id From [Table] Where charindex(id,'1,2,3……‘)>0 and [ST] = 0

------解决方案--------------------
引用:
Quote: 引用:

因为in本质就是or,优化器对每个or都要做分析,过多的or会导致优化器无法分析,最后报错

我觉得不用那么麻烦把。
讨论下,这个可用?
Select id From [Table] Where charindex(id,'1,2,3……‘)>0 and [ST] = 0
这个要看数据量了,当年遇到这个类似情况的时候还不会用charindex,所以没测过是否不抱错。不过这个函数基本上就是表扫描或索引扫描,所以可能性能没那么好。如果换成集合,加上索引,可能能用得上
------解决方案--------------------
他要in那么多的数据,怎么着效率也上不了去。至少实现起来简单,但是效率还得实测。
------解决方案--------------------
引用:
他要in那么多的数据,怎么着效率也上不了去。至少实现起来简单,但是效率还得实测。
in一千多个,以前我处理过的,执行计划直接无法生成,后来减少到500多个,跑了2个小时,我换成表join之后,2分钟就出来了
------解决方案--------------------
你用局部临时表就可以避免并发问题,tempdb开大一点,放到IO快的盘上,问题不大。另外一个字段进行处理,就要看看如何整合进去。
------解决方案--------------------
用join你是觉得麻烦还是慢?
------解决方案--------------------
假设你已经有了这个ID的集合,假设为#t,那么你现在需要怎么对另外一个字段进行判断?
------解决方案--------------------
在你这个例子中,In始终是个性能杀手
------解决方案--------------------

Select id From [Table] Where [id] in(select id from 表) and [ST] = 0

如果这些ID是程序中华拼接的 就没好办法了
------解决方案--------------------
楼主还是试试看能不能用left join吧 估计其他的方法都不太好用
------解决方案--------------------
引用:
4、用DBA_Huangzj 提供的方法,只能取1600多条记录,耗时1秒左右,
将@s varchar(8000)修改为@s nvarchar(max),与方法3同样的ID集,耗时超过5分钟后未完成,手动取消执行。
你为啥要换成nvarchar?varchar也有max的啊。left join就