2012-10-23 56 views
7

我有一個有超過10億行時間序列數據的表,它具有夢幻般的插入性能,但是(有時)選擇性能非常糟糕。SQL Server:時間序列數據性能

tblTrendDetails(PK是有序如圖所示):

PK TrendTime datetime 
PK CavityId  int 
PK TrendValueId int 
    TrendValue real 

表不斷在新的數據拉和清除舊數據,因此插入和刪除的性能需要保持精力充沛。

當執行查詢時,如以下,性能差(30秒):

SELECT * 
FROM tblTrendDetails 
WHERE TrendTime BETWEEN @inMinTime AND @inMaxTime 
    AND CavityId = @inCavityId 
    AND TrendValueId = @inTrendId 

如果我再次執行相同的查詢(具有類似的時間,但是任何@inCavityId@inTrendId),性能是非常好(1秒)。性能計數器顯示,在第一次運行查詢時磁盤訪問是罪魁禍首。

關於如何提高性能而不會(顯着)影響插入或刪除性能的任何建議?任何建議(包括完全更改底層數據庫)都是受歡迎的。

+1

PK羣集?任何索引? –

+1

@TimLehner是的.. PK是成簇的。沒有(其他)索引。 – pilotcam

回答

6

後續對相同或相似數據的查詢運行得更快的事實可能是由於SQL Server caching your data。也就是說,是否有可能加快這個初始查詢?

驗證查詢計劃:

我的猜測是,你的查詢應導致索引查找,而不是索引掃描(或更糟的是,表掃描)。請使用SET SHOWPLAN_TEXT ON;或類似功能進行驗證。使用between=作爲您的查詢確實應該take advantage of the clustered index,但that's debatable

索引碎片:

這可能是你的聚集索引(在這種情況下,主鍵)相當分散畢竟這些插入和刪除。我可能會檢查這與DBCC SHOWCONTIG (tblTrendDetails)

您可以使用DBCC INDEXDEFRAG (MyDatabase, tblTrendDetails)對錶格索引進行碎片整理。 這可能需要一些時間,但可以讓桌面保持可用狀態,並且可以在沒有任何惡意副作用的情況下停止操作。

您可能需要更進一步並使用DBCC DBREINDEX (tblTrendDetails)。不過,這是一個離線操作,所以只有在不需要訪問表時才應該這樣做。

這裏描述了一些區別:Microsoft SQL Server 2000 Index Defragmentation Best Practices

請注意,您的事務日誌可能會在整理大型表時增長很多,而且可能需要很長時間。

分區視圖:

如果這些不亡羊補牢(或碎片不是問題),你甚至可以想看看partitioned views,在其中創建了一堆各種底層基本表的記錄範圍,然後將它們全部放在視圖中(替換原始表格)。

更好的東西:

如果這些選擇的性能是一個真正的業務需求,你可以做出更好的硬件情況:驅動器速度,更大的內存等。如果您的驅動器的兩倍,快,那麼這個查詢將運行一半的時間,是嗎?另外,這對你來說可能不適用,但我發現新版本的SQL Server確實更快,更多的選擇和更好的維護。我很高興將我公司的大部分數據移至2008R2。但我離題...

+2

+1爲一個非常徹底和明確的答案。在發佈問題之前,我已通過驗證查詢計劃。但我沒有想到索引碎片。 'SHOWCONTIG'肯定揭示了碎片。我正在運行一個'INDEXDEFRAG'。 – pilotcam