適用於:SQL Server
Azure SQL 資料庫
Azure SQL 受控執行個體
Azure Synapse Analytics
Analytics Platform System (PDW)
Microsoft Fabric 中的 SQL 資料庫
有關選項和建議,如何使用標準 SQL 的批量載入和緩慢插入方法,將資料載入至資料行存放區索引中。 將資料載入至資料行存放區索引是任何資料倉儲程序中不可或缺的一部分,因為它會將資料移至索引,以準備進行分析。
列存儲索引的新手嗎? 請參閱資料行存放區索引 - 概觀和資料行存放區索引架構。
什麼是大量載入?
「大量載入」 指的是在資料存放區中新增大量資料列的方式。 這是將資料移至資料行存放區索引的最有效方式,因為它是以資料列批次的方式操作。 大量載入會將資料列群組填滿至最大容量,並將其直接壓縮到資料行儲存空間。 只有在載入結束時未達到每個資料列群組至少 102,400 個資料列的資料列,才會移至差異存放區。
若要執行大量載入,您可以使用 bcp 公用程式、Integration Services,或從暫存資料表中選取資料列。
如圖所示,批量載入︰
- 不會對資料進行預先排序。 資料會按接收的順序插入至資料列群組。
- 如果批次大小 >= 102400,資料列會直接載入到壓縮的資料列群組中。 您應該選擇批次大小 >=102400 來有效執行批量導入,因為您可以避免在數據列最終由背景线程tuple mover(TM)移至壓縮數據列群組之前,將數據列移至差異數據列群組。
- 如果批次大小小於 < 102,400,或如果剩餘的資料列小於 < 102,400,則資料列會被載入差異資料列群組。
注意
在具有非叢集資料行存放區索引資料的資料列存放區資料表上,SQL Server 一律會將資料插入基底資料表。 資料從不會直接插入列存索引。
大量載入具有下列內建的效能最佳化方式:
平行載入:您可以執行多個並行大量載入 (bcp 或大量插入),其中每個載入操作都會載入不同的資料檔案。 與 SQL Server 的資料列存放區批量載入不同,您不需要指定
TABLOCK
,這是因為每個批量匯入執行緒會將資料專門載入不同的資料列群組(壓縮或增量資料列群組),並持有對這些群組的獨占鎖定。縮減記錄:將資料直接載入壓縮資料列群組時,會導致記錄大小大幅減少。 例如,如果數據壓縮為10倍,則相應的交易日誌大約只有原來的1/10大小,而不需要
TABLOCK
或大容量記錄/簡單恢復模式。 進入 delta 資料列群組的所有資料都會完整記錄。 這包括任何少於 102,400 個資料列的批次大小。 最佳做法是使用 batchsize >= 102400。 因為不需要TABLOCK
,因此您可以平行載入數據。最低限度記錄: 如果您遵循最低限度記錄的必要條件,則可以進一步縮減記錄。 不過,不同於將數據載入資料列,
TABLOCK
會對數據表進行X
(獨佔)鎖定,而不是BU
(大量更新)鎖定,因此無法進行平行數據載入。 如需鎖定的詳細資訊,請參閱鎖定和資料列版本管理。鎖定優化: 當將數據載入壓縮後的列群組時,系統會自動取得該列群組的鎖定。 不過,當在載入大量資料時,系統會為 delta 數據列群組取得鎖定,
X
但資料庫引擎仍然會取得頁面和範圍鎖定,因為X
delta 數據列群組的鎖定並不屬於鎖定層次結構的一部分。
如果您在資料行存放區索引上有一個非叢集 B-tree 索引,則對於該索引本身而言,沒有任何鎖定或記錄的最佳化,但如上所述的叢集資料行存放區索引最佳化依然適用。
規劃大量載入的規模以減少差異資料列群組
當大部分資料列被壓縮到資料行存放區,而不是停留在 delta 列存放區時,資料行存放區索引的效能最佳。 最佳做法是調整負載的大小,以讓資料列直接進入欄儲存區,並盡量略過 delta 存放區。
下列情境說明載入的資料列何時會直接進入資料行存放區,或何時會進入增量存放區。 在範例中,每個資料列群組可以有 102,400-1,048,576 個資料列。 實際上,在記憶體不足的情況下,資料列群組的大小上限可能會小於 1,048,576 個資料列。
要大量載入的資料列 | 已新增資料列至壓縮資料列群組 | 已新增至差異資料列群組的資料列 |
---|---|---|
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 object_id, index_id, partition_number, row_group_id, delta_store_hobt_id,
state, state_desc, total_rows, deleted_rows, size_in_bytes
FROM sys.dm_db_column_store_row_group_physical_stats;
此螢幕快照顯示批次載入的列群組和 Delta 存放區。
使用暫存資料表來改善效能
如果您只是在執行其他轉換之前暫時存儲資料,將資料載入堆積表格比載入到叢集欄存儲表要快得多。 此外,將資料載入 [暫存資料表] [暫存] 也會比將資料表載入永久儲存體還要快的多。
資料載入的一個常見模式,是將資料先載入暫存表格再進行一些轉換後,使用下列命令將其載入目標資料表:
INSERT INTO [<columnstore index>]
SELECT col1 /* include actual list of columns in place of col1*/
FROM [<Staging Table>]
此命令會以類似於 bcp 或大量插入的方式,將資料以單一批次載入至資料行存放區索引。 如果暫存表中的資料列數量 < 102400,則資料列會載入至差異資料列群組,否則會直接載入至壓縮資料列群組。 有一項很重要的限制是,這項 INSERT
作業為單一執行緒。 若要平行載入資料,可以建立多個暫存表格,或是針對暫存表格發出 INSERT
/SELECT
命令,使用不重疊的資料列範圍。 SQL Server 2016 (13.x). 中已無這項限制。 下列命令會從暫存表格以平行方式載入資料,但您必須指定 TABLOCK
。 您可能會發現這與稍早所述的大量載入有所矛盾,但主要差異在於從暫存表格以平行方式載入資料會在相同的交易下執行。
INSERT INTO [<columnstore index>] WITH (TABLOCK)
SELECT col1 /* include actual list of columns in place of col1*/
FROM [<Staging Table>]
從暫存表格載入叢集資料行存放區索引時,提供下列最佳化方式:
- 記錄優化: 當數據載入壓縮的數據列群組時,記錄會減少。
-
鎖定優化: 將數據載入壓縮的數據列群組時,
X
會取得數據列群組的鎖定。 然而,當大量載入進入差異行群組時,會取得行群組的X
鎖, 但 Database Engine 仍會取得頁面和範圍鎖, 因為X
行群組鎖不是鎖層次結構的一部分。
如果您有一或多個非叢集索引,則對於索引本身而言,無論是鎖定還是記錄方面都沒有最佳化,但如前所述,對叢集資料行儲存索引的最佳化仍然存在。
什麼是滴入式插入?
「逐步插入」 指的是將個別資料列逐步移入資料行存放區索引的方式。 緩慢插入會使用 INSERT INTO 陳述式。 透過漸進插入,所有資料列都會進入 Delta 存放區。 此功能對於少量資料列很有用,但不適用於大量的數據處理。
INSERT INTO [<table-name>] VALUES ('some value' /*replace with actual set of values*/)
注意
使用 INSERT INTO 將值插入叢集資料行存放區索引的並行執行緒,可以將資料列插入到相同的差異存放區資料列群組中。
資料列群組包含 1,048,576 個資料列之後,差異資料列群組會標示為已關閉,但仍可供查詢、更新/刪除操作之用,但新插入的資料列會進入現有或新建立的差異存放區資料列群組。 有一個稱為 Tuple mover(TM) 的背景執行緒會每隔大約 5 分鐘定期壓縮封閉的差異列群組。 您可以顯式調用下列命令來壓縮封閉的Δ資料列群組。
ALTER INDEX [<index-name>] on [<table-name>] REORGANIZE
如果想要強制結束差異資料列群組並壓縮它,可以執行下列命令。 如果已完成載入資料列,而且預期不會再有任何新的資料列,可以執行此命令。 明確地關閉並壓縮 delta 資料列群組,可以進一步節省儲存空間,並改善分析查詢效能。 如果您預期不會插入新資料列,那麼最佳做法是叫用此命令。
ALTER INDEX [<index-name>] on [<table-name>] REORGANIZE with (COMPRESS_ALL_ROW_GROUPS = ON)
載入至已分區資料表的方式
若為分割數據,Database Engine 會先將每個資料列指派給分割區,然後對分割區中的數據執行列存儲作業。 每個分割區都有自己的資料列群組以及至少一個增量資料列群組。