2

这是一张表:

CREATE TABLE Meetings
(
  ID int PRIMRY KEY IDENTITY(1,1)
  StartDate DateTime NOT NULL,
  EndDate DateTime NULL,
  Field1 varchar(50),
  Field2 varchar(50),
  Field3 varchar(50),
  Field4 varchar(50)
)

有几千行。数据范围可以是不同的大小(从几天到 50 年)。

这是一个查询:

DECLARE @ApplicableDate DateTime

SELECT ID, StartDate, EndDate, Field1, Field2, Field3, Field4
FROM Meetings
WHERE StartDate <= @ApplicableDate AND
  (EndDate is null || @ApplicableDate <= EndDate)

由于日期范围可能很大,因此可能会返回表的大部分(20%-50% 的行)。

查询以简单的方式表示我想要的行,但性能很差。无论我添加什么索引,它都会进行聚集索引扫描。我试过了:

  • 开始日期
  • 开始日期,结束日期

如何提高此查询的性能?


我已经查看了这个问题这个问题的答案。这些解决方案对我的情况没有帮助 - 我真的不想通过创建一个单独的日期表来将查询转换为相等查询(修改结束日期或为空时会发生什么情况? ),或者通过变形数据以适应空间索引。

不过,我对可能对数据结构进行的修改持开放态度(特别是如果它们不添加行,也不使用奇怪的数据类型)..

4

2 回答 2

3

我假设您在 SQL Server 上使用我的语法。

将 ID 上的主键设为非聚集索引。

ID int PRIMARY KEY NONCLUSTERED IDENTITY(1,1),

在 StartDate 列上创建聚集索引。

CREATE CLUSTERED INDEX ix_Meetings_StartDate
ON Meetings (StartDate)

按原样尝试您的查询。尽管数据的存储方式可能与集群 PK 的存储方式类似,但现在查询引擎将提前知道数据是按开始日期进行集群的。

于 2010-08-06T21:45:32.833 回答
2

如果查询返回 20%-50% 的记录,那么扫描多次是最佳选择。如果你有一个索引,你总是要在索引中找到数据,然后在表中包含一个记录地址,然后你必须从磁盘中获取包含该记录的页面,有索引中相邻记录被传播的风险整个磁盘。

如果您确实需要那么多记录并且性能很差,那么可以检查以下内容:

  • 磁盘速度有问题吗?
  • 是网络带宽吗?
  • 您是否受限于 RAM/缓存?
于 2010-08-06T21:25:22.633 回答