2008-09-23 117 views
15

讓我們假設你有三列一個巨大的表,如下圖所示:SQL Server - 分區表與集羣索引?

[id] INT NOT NULL, 

[date] SMALLDATETIME NOT NULL, 

[sales] FLOAT NULL 

還假定您僅限於一個物理磁盤和一個文件組(主)。您預計此表在100個日期(容易1B +記錄)中保持10,000,000個ID以上的銷售額。與許多數據倉庫場景一樣,數據通常會按日期順序增長(即,每次執行數據加載時,您將插入新日期,並且可能會更新某些更新的數據日期)。出於分析目的,數據通常會被隨機查詢並彙總到〜10,000個id,這些id將通過與另一個表的聯接來指定。通常,這些查詢不指定日期範圍,或者指定非常寬的日期範圍,這引起我的問​​題:索引/分區此表的最佳方法是什麼?

我已經想了一段時間,但是卡具有衝突的解決方案:

選項#1:隨着數據將依次被日期被加載,定義羣集索引(和主鍵)作爲[日期],[id]。還可以在日期上創建「滑動窗口」分區功能/方案,以便將新數據快速移入/移出表格。有可能在ID上創建非聚集索引以幫助查詢。

預期的結果#1:這種設置會非常快的數據加載的目的,但次優的,當涉及到分析原文,在最壞的情況下(不受日期限制,不吉利與集ID的的查詢),可以讀取100%的數據頁面。

選項2:由於數據一次只能查詢一小部分ids,因此將聚集索引(和主鍵)定義爲[id],[date]。不要打擾創建分區表。

預期結果#2:由於我們無法再按日期快速限制,因此在加載數據時預期會有巨大的表現。當涉及到我的分析查詢時,預計會帶來巨大的性能收益,因爲它可以最大限度地減少讀取的數據頁的數量。

選項#3:集羣(和主鍵)如下:[id],[date]; 「滑動窗口」分區功能/方案日期。

預期結果#3:不知道該期待什麼。考慮到聚集索引中的第一列是[id],因此(這是我的理解)數據是按ID排列的,我希望我的分析查詢具有良好的性能。但是,數據按日期進行分區,這與聚簇索引的定義相反(但仍與日期成爲索引的一部分對齊)。我還沒有找到很多說明這種情況的文檔以及我可能從中獲得哪些性能優勢,這會帶來我最終的獎金問題:

如果我在一個文件組上創建表一個磁盤,在一列上有一個聚簇索引,在同一列上定義一個分區會帶來什麼好處(加載數據時除了分區切換)?

回答

0

如果你在select語句中使用分區,那麼你的cn獲得了一定的速度。

如果你不使用它,只使用「標準」選擇,那麼你沒有任何好處。

在你原來的問題:我會建議你選項#1與包括id的非聚集索引。

3

當本地化I/O時,聚簇索引會爲查詢帶來性能優勢。 Date是傳統的分區策略,因爲許多D/W查詢按日期查看運動。

分區表的經驗法則表明分區大小應該在10米左右。

從多樣化分析工作負載的聚集索引中看到很多性能增益會有點不尋常。查詢優化器將使用一種名爲'Index Intersection'的技術來選擇行,而不會觸及事實表。查看Here瞭解我在另一個問題上所做的文章,該文章通過一些鏈接更深入地解釋了這一問題。 聚集索引可能參與也可能不參與索引交集,因此您可能會發現它在一般查詢工作負載上獲得的相對較少。

您可能會發現聚集索引爲您帶來一些收益的情況,特別是如果您有在ETL過程中計算的派生計算(例如Earned Premium)。在這種情況下,您可能會獲得一些好處。如果你有一個特定的查詢,你知道它會一直執行,爲此使用聚簇索引是有意義的。如果您希望這種類型的查詢成爲應用程序完成的絕大多數工作,則選項#2和#3只會對您有很大的好處。

對於一個靈活的系統,一個帶有ID索引的簡單日期範圍分區(如果分區擁有一個範圍,那麼日期可能會讓你獲得與任何其他性能相當的性能,你可能從集羣索引受限。情況下,您也可以從建立多維數據集在數據和確保聚合針對此查詢正確設置得到一些里程

0

我會做到以下幾點:。

  • 非聚集的索引[ Id]
  • [日期]上的聚集索引
  • 將[銷售]數據類型轉換爲數字而不是浮點數
+0

你最後一點很有趣。從float轉換爲numeric會帶來什麼樣的性能好處? – 2008-09-23 13:42:40

+1

您可以更準確地瞭解您正在存儲的數據,並且數字數據類型是精確數字,其中浮點數是近似數字。 – GateKiller 2008-09-23 18:04:46

7

此表非常窄。如果真正的表格會很窄,那麼你應該樂意使用表掃描而不是索引 - >查找。

我這樣做:

CREATE TABLE Narrow 
(
    [id] INT NOT NULL, 
    [date] SMALLDATETIME NOT NULL, 
    [sales] FLOAT NULL, 
    PRIMARY KEY(id, date) --EDIT, just noticed your id is not unique. 
) 

CREATE INDEX CoveringNarrow ON Narrow(date, id, sales) 

該處理點查詢與尋求與對日期的標準和標識的標準掃描有限範圍廣泛的查詢。沒有索引的每條記錄查找。是的,我已經將寫入時間加倍(和使用的空間),但這很好,imo。


如果有一些需要特定的數據塊(這需要的是通過剖析 !!證明),我想創建一個集羣視圖靶向表的那個部分。

CREATE VIEW Narrow200801 
AS 
SELECT * FROM Narrow WHERE '2008-01-01' <= [date] AND [date] < '2008-02-01' 
--There is some command that I don't have at my finger tips to make this a clustered view. 

集羣意見,可以在查詢中通過名稱來使用,或者優化器將選擇使用WHERE子句是適當的羣集意見時,FROM和。例如,這個查詢將使用聚集視圖。請注意,查詢中引用了基表。

SELECT SUM(sales) FROM Narrow WHERE '2008-01-01' <= [date] AND [date] < '2008-02-01' 

由於指數讓你做特定的列方便到達... 集羣視圖讓你做特定的行方便到達。

0

按日期對錶進行分區。多個水平分區將比具有多行的一個大表更具性能。

0

如果插入的日期時間分辨率爲3.33毫秒,插入將會更快地插入日期列中的聚集索引不好。 如果你這樣做,你會得到2個具有相同值的鍵,你的索引將不得不得到另一個內部的uniquifier,這將增加它的大小。

我會去#2的選項。