2010-08-06 38 views
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%)。

該查詢以簡單的方式表示我想要的行,但性能很差。它執行聚簇索引掃描,無論我添加哪個索引。我已經試過:

  • 起始日期
  • 開始日期,結束日期

我怎樣才能提高此查詢的性能?


我已經審查了this questionthis one太多的答案。這些解決方案對我的情況沒有幫助 - 我並不想通過創建單獨的日期表來將業務數據弄糟,以便將查詢轉換爲平等查詢(修改結束日期時會發生什麼情況,或者是否爲空? ),或通過變形數據以適合空間索引。

,我依然是開放的可能修改的數據結構(特別是如果他們不添加行,也不要使用奇怪的數據類型)..

+0

你可以嘗試:'WHERE @ApplicationDate BETWEEN startdate AND ISNULL(enddate,'9999-12-31')',使用ISNULL將null enddates更改爲sentinel值。 COALESCE是一個選項,但ISNULL往往會更快:http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ISNULL_COALESCE – 2010-08-06 21:59:09

回答

2

如果查詢返回20%-50%記錄,那麼掃描是多次的最佳選擇。如果您有索引,則必須始終在索引中查找數據,然後索引中包含一個記錄地址,然後您必須從磁盤獲取包含此記錄的頁面,否則索引中的相鄰記錄可能會散播遍佈磁盤。

如果你真的需要很多的記錄和表現不好的話,說不定檢查以下內容:

  • 是對磁盤速度的問題?
  • 它是網絡帶寬嗎?
  • 你在RAM/Cache中受限制嗎?
3

我假設你在SQL Server上是爲了我的語法。

使ID爲非聚集索引的主鍵。

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

在StartDate列中創建一個聚集索引。

CREATE CLUSTERED INDEX ix_Meetings_StartDate 
ON Meetings (StartDate) 

請按原樣查詢。即使數據存儲方式與您使用集羣PK的方式類似,現在查詢引擎會事先知道數據是按開始日期聚集的。