2

我有一些数据想从我们的 SQL 服务器中提取出来。

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

不过,我需要对此数据运行报告。

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

开始更新

  • 此表中通常有 5 到 15 个条目,每个Serial_Number.
  • 最多有 10 台机器向该表写入数据,因此Date_Time可能有相同的值

结束更新

此过程需要一段时间,但在列表中的不同序列号之间,我可以使用进度条更新 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

4 回答 4

2

Table1 中的索引 Serial_Number 和 Date_Time(具有单独的索引,而不是单个复合索引),这对您来说应该表现得相当好,除非表真的非常巨大。

使用 Serial_Number 上的一个索引和 (Date_Time, Serial_Number) 上的第二个索引可能会加快速度。第二个索引覆盖子查询,允许仅从索引中回答它。

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

于 2012-10-09T21:05:23.987 回答
1

好吧,在没有索引的幼稚情况下(听起来像是您的情况),您将不得不扫描所有行Table1以执行DISTINCTonSerial_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 顺序排序。根据您运行的查询的确切类型,对执行计划的进一步处理将有助于识别可能对您的性能有很大帮助的其他索引。

于 2012-10-09T21:06:51.147 回答
1

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

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

我认为不需要DISTINCT关键字 for Serial_Number,因为在外部查询的结果中不会消除重复项。

这样做有什么问题?

SELECT Serial_Number, Col1, Col2, Col3
FROM Table1
WHERE Date_Time Between @startDate AND @endDate

这应该与您的原始查询执行相同的操作。但它会消除昂贵的嵌套查询。

只需放置一个索引Date_Time,它应该可以工作。这也将消除对索引的需要Serial_Number

于 2012-10-09T22:15:40.577 回答
0

显然,没有办法知道可以的最大长度是多少WHERE X IN (...)

目前,这就是答案。

如果在稍后的某个时间点,有人出现并发现相反的东西,请发布该答案,我会这样标记。

谢谢,乔

于 2012-10-11T19:05:38.233 回答