接上文:SQL Server 列存儲索引性能總結(3)——列存儲的鎖,列存儲的其中一個強項在於非常高的壓縮率,如果沒有這個壓縮功能,列存儲不可能有極大的性能提升。本文就來演示一下壓縮方面的內容。
案例測試
壓縮率高不高直接看大小的變化已經足夠了,這次我們使用ContosoRetailDW庫的FactOnlineSales表,這個表有1200萬數據,可以作爲一個借鑑,我們先把數據挪到一個堆表:
select * into [FactOnlineSales_Heap]
from [dbo].[FactOnlineSales]
使用sp_spaceused命令檢查當前大小:
常規聚集列存儲索引
接下來創建聚集列存儲索引:
create clustered columnstore index CCI on dbo.FactOnlineSales_Heap
再次檢查大小: data從2020440 KB (1973MB)降到了172512 KB(168MB)
Archive聚集列存儲索引
當然不會簡單地到此結束,我們再來試一下另外一個參數:DATA_COMPRESSION = COLUMNSTORE_ARCHIVE
alter index all on dbo.FactOnlineSales_Heap rebuild with ( DATA_COMPRESSION = COLUMNSTORE_ARCHIVE );
然後獲取大小,看看現在到底多大了?76400 KB(76MB)!
比常規的聚集列存儲又少了一半以上。不過單純的空間減少並不代表一切。爲什麼呢?因爲這個選項從名字就可以看出是用來做“歸檔”的,針對那些很少用的數據,甚至可以理解爲不用去怎麼查詢和操作的數據,幾年用一次的那種,一旦頻繁使用,那麼解壓過程可能會非常慢。
drop index cci on FactOnlineSales_Heap
GO
exec sp_spaceused '[FactOnlineSales_Heap]'
行壓縮傳統聚集索引
爲了測試對比,我們這次來建一個傳統的行存儲聚集索引,並且使用行壓縮功能:
create clustered index [CIX] on dbo.[FactOnlineSales_Heap] ( OnlineSalesKey asc ) with ( DATA_COMPRESSION = ROW );
空間爲888392 KB(888MB),另外index_size也從個位數升到4位數。
頁壓縮傳統聚集索引
接下來我們創建頁壓縮的聚集行存儲索引:
create clustered index [CIX] on dbo.[FactOnlineSales_Heap] ( OnlineSalesKey asc ) with (DROP_EXISTING = ON, DATA_COMPRESSION = PAGE);
這一次的結果又不一樣,350M,其實傳統壓縮中,頁壓縮已經足夠了,因爲頁壓縮自帶有行壓縮的功能。
在進行壓縮錢,關於壓縮的效果,可以使用這個存儲過程來評估壓縮效果,可以輔助你選擇:
sp_estimate_data_compression_savings
[ @schema_name = ] 'schema_name'
, [ @object_name = ] 'object_name'
, [@index_id = ] index_id
, [@partition_number = ] partition_number
, [@data_compression = ] 'data_compression'
[;]
@schema_name: 表或索引的schema。
@object_name: 表或索引視圖的名字。
@index_id: 可以指定某個索引,如果表上沒有索引,可以使用0或NULL。
@partition_number: 分區號,如果沒有索引,也要使用NULL。
@data_compression: 可以指定NONE(不壓縮),ROW(行壓縮),PAGE(頁壓縮),COLUMNSTORE(列存儲)和在SQL 2019出現的COLUMNSTORE_ARCHIVE 進行壓縮評估。
這個存儲過程會提取一些樣本,然後在TempDB上創建並計算。
小結
如果考慮一個數據庫甚至數據表超過了TB級別,那麼往往可以節省好幾TB的空間。
聚集列存儲索引使用RLE(Run-length Encoding,運行長度編碼)技術來壓縮,適合表中有很多重複數據的情況。對於Archive壓縮,SQL Server使用了微軟的XPRESS 壓縮技術進一步壓縮。
使用Archive壓縮的索引,在查詢時會比常規的聚集列存儲索引更慢,同時CPU和內存使用率也更高。所以我再次說一下過往已經說過很多次的話,只要允許你選擇用還是不用的選項,就要注意,因爲它們都有適用場景和前提條件,不要只看到優點就忽視缺點。Archive更適合用於分區環境下,某些已經可以歸檔的分區上。
下面是一個結果對比,可以看出常規行存儲已經足夠好,不過要注意兩個事情:
- 沒有絕對完美的方案,需要看自己環境的需要。
- 無論哪種壓縮,都是CPU密集型操作,同時解壓也是需要考慮的。