2010-11-22 55 views
9

我有一個場景,其中有大量關於項目的狀態數據。 該項目的狀態從分鐘到分鐘更新,在不久的將來約有50,000件物品。因此,在一個月內,將會有約22.23億行數據。在獲得舊數據之前,我必須在主表中保留至少3個月的時間。我必須計劃根據特定項目(其ID)和數據範圍(通常最多一個月範圍)來實現快速查詢 - 例如,從表中選擇A,B,C其中ItemID = 3000和'2010-10-01'和'2010-10-31 23:59:59.999'之間的日期'在SQL Server 2008中爲查詢性能分區

所以我的問題是如何設計一個分區結構實現那個?

目前,我基於「項目的唯一標識符」(一個int)mod「分區數」進行分區,以便所有分區平均分配。但是它的缺點是在表上保留一列作爲分區函數的分區列,因此將該行映射到其分區。所有這些都增加了一點額外的存儲空間。另外,每個分區都映射到不同的文件組。

+1

這是一些負載。閱讀[這裏](http://sqlblog.com/blogs/paul_nielsen/archive/2007/12/12/10-lessons-from-35k-tps.aspx)關於大量寫入(你有50k行*每秒*來電)。我很好奇你將如何解決這個問題:我沒有這種數量/增長率的經驗) – gbn 2010-11-22 18:58:38

+0

你想要設計寫查詢效率還是讀查詢效率?你有什麼樣的讀取負載? – 2010-11-30 12:56:24

回答

10

對於查詢性能,永遠不會執行分區。隨着分區的表現將總是更糟糕,最好的你可以希望是沒有大的迴歸,但從來沒有改善。

對於查詢性能,分區可以做的任何事情和索引可以做得更好,這應該是你的答案:適當的索引。

分區對於IO路徑控制情況(分佈在歸檔/當前卷)或ETL負載中的快速切入轉出場景非常有用。所以我會理解,如果你有一個滑動窗口和按日期分區,所以你可以快速切換出不再需要保留的數據。

分區的另一個小例子是最後一頁插入鎖存爭用,如Resolving PAGELATCH Contention on Highly Concurrent INSERT Workloads中所述。

您的分區方案和用例似乎不適合任何應用場景(也許是最後一種場景,但從描述中不清楚),因此很可能會傷害性能。

0

我同意Remus的看法,按照你自己的結果顯示,分區並不會改善事物。

忘記分區,索引ID和日期,並運行在有巨大內存的盒子上;有什麼結果?

1

我不完全同意Remus Rusanu。我認爲如果存在邏輯原因(與您的用例相關),分區可能會提高性能。我的猜測是你只能對itemID進行分區。另一種方法是使用日期,但是如果你不能預測日期範圍不會跨越給定分區的邊界(沒有查詢肯定會在一個月內),那麼我會堅持itemId分區。

如果只需要計算一些項目,另一個選項是有一個覆蓋索引:在主分化字段(itemId)上定義一個INDEX,它包含需要計算的字段。

CREATE INDEX idxTest ON itemId INCLUDE quantity; 
1

應用型劃分實際上可以查詢性能有益。在你的情況下,你有50K項目和2G行。例如,您可以創建500個表,每個表名爲status_nnn,其中nnn介於001和500之間,並在這些表中「分區」您的項目狀態,其中nnn是項目ID的函數。這樣,給定一個項目ID,您可以將您的搜索優先限制爲整個數據的0.2%(大約4M行)。

這種方法有很多缺點,因爲您可能需要處理動態sql和其他不愉快的問題,尤其是如果您需要彙總不同表中的數據時。但是,它肯定會提高某些查詢的性能,s.a.你提到的那些。

基本上可應用的分區類似於創建非常廣泛和平坦的索引,針對非複製數據的特定查詢進行了優化。

應用程序分區的另一個好處是,您可以在理論上(取決於您的用例)在不同的數據庫甚至不同的服務器之間分配您的數據。再次,這很大程度上取決於您的具體要求,但我已經看到並使用了大量數據集(數十億行),其中應用程序分區工作得很好。