何時仍需要使用聚集列儲存索引的維度表?
我在我的報告數據庫中使用 MS SQL Server 2016 Clustered Columnstore Indexing(我們稱之為 CCI)。
在最初的設計中,我考慮的是星型模式,但後來我開始使用 CCI。現在我放棄了許多維度表,轉而將字元串直接展平到“事實”表中。我保留維度表的唯一地方是當該維度具有經常更改的屬性並且要求使更改的屬性適用於所有歷史記錄時。我做了這麼多讓一位擁有更多 DW 經驗但沒有空閒時間探索 CCI 的同事感到沮喪。
看起來作為單獨列儲存在磁碟上的平面表(以及提供的大規模壓縮)根本不需要狹窄。使用 CCI 時,何時還需要維度表?
我認為您的問題不適用於任何支持列式儲存的 RDBMS。我是從 SQL Server 的角度寫我的答案,大多數原因取決於特定於 SQL Server 的實現細節。
使用 CCI 時,何時還需要維度表?
1. 維度表的變化量使得更新 CCI 事實表變得不切實際
對於 500 M 行的事實表,如果某些維度列以不幸的方式更改,您可能需要更新 CCI 中的數億行。我知道這樣做的唯一實用方法是重寫整個表或執行刪除 + 插入。對於刪除 + 插入方法,您可能需要將所有列的數據寫入暫存區,等待串列刪除查詢完成(除非您可以按分區刪除),讀取所有行的所有列對於可能包含需要更改的行的行組,依此類推。編碼可能很麻煩,轉換數據的成本也很高。隨著事實表變寬,問題會變得更糟。
2. 由於記憶體限制,字元串列的長度和數量使 CCI 壓縮不切實際
根據您建構 CCI 的方式,對字元串列的記憶體授予請求可能會失控。例如,列
REBUILD
的 aVARCHAR(8000)
請求每個 DOP 6.5 GB,並隨著列長度而縮小。CCI 插入的記憶體授予請求在 25 秒時超時(據我所知,無法更改)。這意味著如果您沒有足夠的記憶體來執行壓縮,您的一些 CCI 插入查詢可能會開始直接寫入增量儲存(以及死鎖和其他壞事)。3. 您的 ETL 或維護流程並非旨在防止或清理增量儲存
您在問題中提到“大規模壓縮”,但增量儲存中的數據未壓縮。如果您的 ETL 過程創建了一個堆,然後將該數據壓縮為列儲存格式,那麼您可能會使用比以往更多的臨時空間進行暫存。如果您在分區表中執行大量並行插入操作,您最終可能會得到數千或更多的增量儲存,而這些增量儲存的數據不會被壓縮,依此類推。
4.維度表有很多唯一的、長字元串
SQL Server 2016 的字典大小限制為每列 16 MB。如果一列的唯一值太多,那麼您可能會超過該限制,並且由於字典壓力,行組將被拆分。將字元串列添加到現有 CCI 事實表會導致壓縮行組更小,這會降低壓縮效率和查詢性能。