SQL限制“WHERE X IN(...)”

时间:2012-10-09 21:00:08

标签: sql tsql sql-server-2000

我有一些数据我想要关闭我们的SQL服务器。

这个旧数据库没有任何与之关联的主键,因此提取数据就像查询Excel电子表格(它实际上是多年前发起的那样)。

我需要运行有关此数据的报告。

目前,我获得了给定时间段内不同序列号的列表,然后提取给定序列号的所有记录。对于1个月的时间范围,这可以是1500到3000个序列号。序列号字段的格式为char(20),即使序列号只有15个字符。

BEGIN UPDATE

  • 此表格中每个Serial_Number通常有5到15个条目。
  • 最多有10台机器将数据写入此表,因此可能存在相同的Date_Time

END UPDATE

此过程需要一段时间,但在列表中的不同序列号之间,我可以使用进度条更新Windows窗体,以便管理层知道正在发生的事情以及需要多长时间。

我总是试图让这个查询运行得更快。

现在,我正在考虑使用WHERE子句来提取我需要的数据,例如:

SELECT Col1, Col2, Col3
FROM Table1
WHERE Serial_Number IN (
  SELECT DISTINCT Serial_Number
  FROM Table1
  WHERE Date_Time Between @startDate AND @endDate
)

我的问题是:我是否会遇到任何问题,特别是因为我们在给定的时间范围内有很多不同的序列号。

当然,你知道管理层中有人会在无聊的时候尝试运行一年的数据!然后,他们将尝试自耶稣出生以来运行数据,因为他们没有更好的事情要做。

重申问题WHERE子句IN方法是否限制了我可以传入的项目数量?

4 个答案:

答案 0 :(得分:2)

表1中的索引Serial_Number和Date_Time(具有单独的索引,而不是单个复合索引),除非该表确实非常巨大,否则这应该对您有好处。

使用Serial_Number上的一个索引和第二个(Date_Time,Serial_Number)可能会获得更快的速度。第二个索引涵盖了子查询,允许单独从索引中回答它。

注意:我建议索引,而不是主键,不需要唯一性。

答案 1 :(得分:1)

好吧,在没有索引的天真情况下(听起来像你的情况),你将不得不扫描Table1中的所有行来执行DISTINCT Serial_Number无论如何。所以我不确定它会对你有多大帮助。

我强烈推荐以下内容:

  • 使用执行计划确定查询中发生了什么,
  • 使用该信息添加一些相关索引以加快操作速度。

正如我们在此处看到的那样,Date_Time听起来像是Table1中聚集索引的良好候选者。

编辑:

如上所述,要创建非唯一聚簇索引,可以使用以下命令:

CREATE CLUSTERED INDEX IX_Table1_Date_Time
ON Table1 (Date_Time)

(来自http://msdn.microsoft.com/en-us/library/aa258260(v=sql.80).aspx

这将重新排序您的表,以便所有行按Date_Time顺序排序。进一步使用执行计划将有助于识别可能极大地帮助您提高性能的其他索引,具体取决于您运行的查询的确切类型。

答案 2 :(得分:1)

老实说,我认为WHERE条款没有任何好处。

您使用昂贵的内部查询,但不会对结果执行任何有意义的操作。我甚至没有看到你在任何地方得到Serial_Number的结果。但是,根据您的问题,它确实听起来像您需要它。

我认为不需要DISTINCT的{​​{1}}关键字,因为外部查询的结果中不会删除重复项。

这样做有什么问题?

Serial_Number

这应该与原始查询做同样的事情。但它会消除昂贵的嵌套查询。

只需在SELECT Serial_Number, Col1, Col2, Col3 FROM Table1 WHERE Date_Time Between @startDate AND @endDate 上放一个索引即可。这也将消除对Date_Time上的索引的需求。

答案 3 :(得分:0)

显然,没有办法告诉 WHERE X IN (...)的最大长度是多少。

目前,这就是答案。

如果在稍后的某个时间点有人出现并发现相反的情况,请发布该答案,我会将其标记为此。

谢谢, 乔