在 SQL Server 中使用叢集數據行存放區索引的工作。
如需數據行存放區索引的概觀,請參閱 描述的數據行存放區索引。
如需叢集數據行存放區索引的相關信息,請參閱 使用叢集數據行存放區索引。
內容
建立叢集數據行存放區索引
若要建立叢集數據行存放區索引,請先建立數據列存放區數據表做為堆積或叢集索引,然後使用 CREATE CLUSTERED COLUMNSTORE INDEX (Transact-SQL) 語句,將數據表轉換成叢集數據行存放區索引。 如果您想要叢集資料行存放區索引的名稱與叢集索引相同,請使用 [DROP_EXISTING] 選項。
此範例會將數據表建立為堆積,然後將它轉換成名為 cci_Simple 的叢集數據行存放區索引。 這會將整個數據表的記憶體從數據列存放區變更為數據行存放區。
CREATE TABLE T1(
ProductKey [int] NOT NULL,
OrderDateKey [int] NOT NULL,
DueDateKey [int] NOT NULL,
ShipDateKey [int] NOT NULL);
GO
CREATE CLUSTERED COLUMNSTORE INDEX cci_T1 ON T1;
GO
如需更多範例,請參閱 CREATE CLUSTERED COLUMNSTORE INDEX (Transact-SQL)中的一節。
刪除叢集列存儲索引
使用 DROP INDEX (Transact-SQL) 語句卸除叢集資料行存放區索引。 這項作業將會卸除索引,並將列存放區表轉換成行存放區堆積。
將數據載入叢集資料行存放區索引
您可以使用任何標準載入方法,將數據新增至現有的叢集數據行存放區索引。 例如,bcp 大量載入工具、Integration Services 和 INSERT ...SELECT 可以將數據載入叢集資料行存放區索引。
叢集列存儲索引會利用增量存儲,以防止列存儲中的資料列段的碎片化。
載入到分區資料表
針對已分割的數據,SQL Server 會先將每個行指派給分割,然後在該分割的數據上執行列存儲操作。 每個分割區都有自己的行群組和至少一個增量存放區。
Deltastore 載入情境
在列存放區中累積資料列,直到資料列的數目達到資料列群組所允許的最大數目為止。 當增量存放區包含到每個資料列群組的最大資料列數目時,SQL Server 會將資料列群組標示為「CLOSED」。 名為 「tuple-mover」 的背景程式會尋找 CLOSED 資料列群組,並移至資料行存放區,其中數據列群組會壓縮成數據行區段,而數據行區段則儲存在數據行存放區中。
針對每個叢集列存指數,可以有多個增量存放區。
如果一個差異存放區被鎖定,SQL Server 會嘗試鎖定另一個差異存放區。 如果沒有可用的差異存放區,SQL Server 將會建立新的差異存放區。
針對分割資料表,每個分區可以有一個或多個差異存放區。
針對叢集列存儲索引,下列案例描述何時載入的資料列直接進入列存儲,或何時進入差異存儲。
在範例中,每個資料列群組可以有 102,400-1,048,576 個資料列。
| 要大量載入的數據列 | 新增至列存儲的數據行 | 新增至 Deltastore 的數據列 |
|---|---|---|
| 102,000 | 0 | 102,000 |
| 145,000 | 145,000 資料列群組大小:145,000 |
0 |
| 1,048,577 | 1,048,576 資料列群組大小:1,048,576。 |
1 |
| 2,252,152 | 2,252,152 資料列群組大小:1,048,576、1,048,576、155,000。 |
0 |
下列範例顯示將 1,048,577 個數據列載入分割區的結果。 結果顯示,資料行存放區中有一個「壓縮」資料列群組(即壓縮資料行區段),而在差異存放區中則有 1 個資料列。
SELECT * FROM sys.column_store_row_groups;
變更叢集數據行存放區索引中的數據
叢集資料行存放區索引支援插入、更新和刪除 DML 作業。
使用 INSERT (Transact-SQL) 插入一行。 列將會新增至增量存儲區。
使用 DELETE (Transact-SQL) 刪除資料列。
如果數據列位於數據行存放區中,SQL Server 會將數據列標示為邏輯刪除,但在重建索引之前,不會回收數據列的實體記憶體。
如果數據行在 deltastore 中,SQL Server 將以邏輯和物理方式刪除該數據行。
使用 UPDATE (Transact-SQL) 更新資料列。
如果資料列位於欄存儲區中,SQL Server 會將資料列標示為邏輯刪除,然後將更新的資料列插入增量存儲區中。
如果數據列位於差異存放區中,SQL Server 會更新差異存放區中的數據列。
重建叢集數據行存放區索引
使用 CREATE CLUSTERED COLUMNSTORE INDEX (Transact-SQL) 或 ALTER INDEX (Transact-SQL) 來執行現有叢集數據行存放區索引的完整重建。 此外,您可以使用 ALTER INDEX ...REBUILD 以重建特定分割區。
重建流程
若要重建叢集數據行存放區索引,SQL Server:
在重建時取得資料表或分割區上的唯獨鎖定。 數據「離線」,在重建期間無法使用。
藉由實際刪除已從數據表中邏輯刪除的數據列,來重組數據行存放區;已刪除的位元組會在實體媒體上回收。
在重建索引之前,將資料列存放區中的數據與欄資料存放區中的數據合併。 重建完成後,所有數據都會以列存儲格式儲存,而差分存儲區是空的。
將所有數據重新壓縮到數據行存放區。 當重建時,會存在兩個列存儲索引的副本。 重建完成時,SQL Server 會刪除原始的數據行存放區索引。
重建叢集列存儲索引的建議
重建叢集數據行存放區索引有助於移除片段,以及將所有數據列移至數據行存放區。 我們有下列建議:
重建分區,而不是整個資料表。
如果索引很大,重建整個數據表需要很長的時間,而且需要足夠的磁碟空間,才能在重建期間儲存額外的索引複本。 通常只需要重建最近使用的分割區。
針對分割資料表,您不需要重建整個欄存索引,因為只有最近修改的分割區才可能會發生片段化。 事實數據表和大型維度數據表通常會分割,以便在數據表區塊上執行備份和管理作業。
在大量 DML 作業之後重建分割區。
重建磁碟分區將會重組磁碟分區,並減少磁碟記憶體。 重建將會刪除欄存放庫中所有被標記為刪除的資料列,並且會將增量存放庫中的所有資料列移至欄存放庫。
載入數據後重建分區。
這可確保所有數據都儲存在數據行存放區中。 如果同時發生多個載入,則每個分割區最終可能會有多個增量存儲。 重建會將所有差異存放區數據列移至數據行存放區。
重新組織叢集列存儲索引
重新組織叢集數據行存放區索引會將所有 CLOSED 數據列群組移至數據行存放區。 若要執行重新組織,請使用 ALTER INDEX (Transact-SQL)搭配 REORGANIZE 選項。
不需要重組即可將「CLOSED」列群組移至資料行存放區。 Tuple-mover 程式最終會尋找所有 CLOSED 數據列群組,並加以移動。 不過,Tuple-mover 是單一執行緒,而且可能無法快速移動列群組以滿足您的工作負載需求。
重新組織的建議
重新組織叢集數據行存放區索引的時機:
- 在一或多個數據載入之後重新組織叢集數據行存放區索引,以儘快達到查詢效能的優點。 重新組織一開始需要額外的CPU資源來壓縮數據,這可能會降低整體系統效能。 不過,一旦壓縮數據,查詢效能就可以改善。