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
參考
Built-in functions for compression/decompression in SQL Server 2016
[SQL SERVER]LOB資料類型適合儲存在SQL SERVER嗎
[SQL SERVER][Performance]善用資料壓縮#實做