[SQL SERVER]SQL2016-壓縮、解壓縮新函式

SQL2016新增壓縮和解壓縮純量值函式,

將輸入內容透過GZIP演算法壓縮並返回varbinary(max)資料型別,

這些函式對我來說相當實用且重要。

早期沒有壓縮和解壓縮函式,我都自行透過.NET建立CLR function來處理,

主要是針對LOB欄位(大於8000)進行壓縮,一來節省硬碟空間和記憶體耗用量,

二來可提高查詢效能,另外像是永久儲存的資料(不會再變更的),

或不需要全文檢索的大型檔案也都建議進行壓縮,

但現在SQL2016不需要這麼麻煩了,這篇我們來看看壓縮後對效能的影響。

declare @myval varchar(max)=replicate('rico',8000);
select DATALENGTH(@myval) as uncompressed;

declare @myoutval varbinary(max)=compress(@myval);
select DATALENGTH(@myoutval) as compressed;

--壓縮比例
select 100-DATALENGTH(@myoutval)/(DATALENGTH(@myval)*1.0) as compressionRatio

使用資料表測試看看

create table myuncompressed(c1 varchar(max))
--uncompressed
insert into myuncompressed with(tablock)
select replicate('rico',8000)
from sys.objects t1
cross join  sys.objects t2

create table mycompressed(c1  varbinary(max))
--compressed
insert into mycompressed with(tablock)
select compress(c1)
from myuncompressed
--查看資料表大小
sp_spaceused 'myuncompressed'
go
sp_spaceused 'mycompressed'
go

同樣的資料筆數,經過compress後,資料瞬間小的不像話

(還可搭配row或page壓縮,效果更棒—參考[SQL SERVER][Performance]善用資料壓縮#實做)。

 

--壓縮比例
select 100-11240/(4908128*1.0) as compressionRatio

 

查詢效能測試

我簡單列出幾種情況建議使用compress

1.欄位使用LOB並大於8000(參考[SQL SERVER]LOB資料類型適合儲存在SQL SERVER嗎)

2.資料包含太多重複內容

3.壓縮後欄位不考慮使用clustered columnstore index

4.壓縮後欄位不常查詢

select top 990 * from dbo.myuncompressed
go

查詢未壓縮資料,logical read:990、花費時間:252 ms。

select top 990 * from dbo.mycompressed
go

查詢壓縮資料,logical read:9、花費時間:104 ms。

 

兩個查詢整體執行計畫成本差異

 

解壓縮測試

select top 990 * from dbo.myuncompressed
go

select top 990 cast(decompress(c1) as varchar(max)) from dbo.mycompressed
go

查詢透過解壓縮雖然會耗費額外CPU資源,

但整體來說對效能(記憶體、網路頻寬、I/O)還是有很大改善。

 

Enjoy SQL Server 2016

 

參考

COMPRESS (Transact-SQL)

DECOMPRESS (Transact-SQL)

Built-in functions for compression/decompression in SQL Server 2016

[SQL SERVER]LOB資料類型適合儲存在SQL SERVER嗎

[SQL SERVER][Performance]善用資料壓縮#實做

[SQL SERVER][Performance]善用資料壓縮#簡介

[SQL SERVER][Memo]資料壓縮對記憶體影響