Sql-Server

SQL Server 壓縮索引是否在重建時保持壓縮而不指定數據壓縮?

  • January 25, 2019

在使用頁面壓縮ALTER INDEX IX1 REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE)(否則索引會被有效地解壓縮嗎?

重建/重組索引時索引保持壓縮。

創建表和壓縮索引

CREATE TABLE DBO.TEST_INDX(id int, bla varchar(255));
CREATE INDEX IX1 ON dbo.TEST_INDX(id)  WITH (DATA_COMPRESSION = PAGE);

檢查壓縮

SELECT i.name, p.data_compression_desc 
FROM sys.partitions P
INNER JOIN sys.indexes I ON I.object_id = P.object_id AND I.index_id = P.index_id
WHERE P.data_compression > 0 and I.name = 'IX1';

結果

name    data_compression_desc
IX1     PAGE

重建索引

ALTER INDEX IX1 on  DBO.TEST_INDX rebuild 

檢查壓縮

SELECT i.name, p.data_compression_desc 
FROM sys.partitions P
INNER JOIN sys.indexes I ON I.object_id = P.object_id AND I.index_id = P.index_id
WHERE P.data_compression > 0 and I.name = 'IX1'

結果

name    data_compression_desc
IX1     PAGE

禁用它們然後重建會產生不同的結果,因為禁用會刪除索引,同時保留索引定義。

alter index IX1 on  DBO.TEST_INDX DISABLE ;
alter index IX1 on  DBO.TEST_INDX REBUILD ;

結果

name    data_compression_desc

壓縮失去,在不調整索引創建腳本的情況下通過 SSMS 刪除和創建索引時,壓縮定義也會失去。

為什麼?

因為在編寫索引創建語句時不會保留 data_compression 選項。

但是,如果我們禁用索引,則使用壓縮重建,然後再次重建:

alter index IX1 on  DBO.TEST_INDX DISABLE ;
alter index IX1 on  DBO.TEST_INDX REBUILD  WITH (DATA_COMPRESSION = PAGE);
alter index IX1 on  DBO.TEST_INDX REBUILD;

結果

name    data_compression_desc
IX1 PAGE

使用 Ola hallengren 的維護解決方案測試重建

為測試目的修改參數。

添加一些數據以到達一頁,因為 MinNumberOfPages 參數需要這些數據。

INSERT INTO dbo.TEST_INDX(id,bla)
VALUES(5,'test');
go 10 

執行索引優化過程以列印出語句。

EXECUTE dbo.IndexOptimize
@Databases = 'TestDB',
@FragmentationLow = 'INDEX_REBUILD_ONLINE',
@FragmentationMedium = 'INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
@FragmentationHigh = 'INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
@FragmentationLevel1 = 5,
@FragmentationLevel2 = 30,
@Indexes = 'TestDB.DBO.TEST_INDX',
@Execute = 'N',
@MinNumberOfPages = 1;

結果:

Command: ALTER INDEX [IX1] ON [TestDB].[dbo].[TEST_INDX] REBUILD WITH (SORT_IN_TEMPDB = OFF, ONLINE = ON, RESUMABLE = OFF)

Comment: ObjectType: Table, IndexType: NonClustered, ImageTex
t: No, NewLOB: No, FileStream: No, ColumnStore: No, AllowPageLocks: Yes, PageCount: 1, Fragmentation: 0
Outcome: Not Executed
Duration: 00:00:00
Date and time: 2019-01-09 14:48:12

執行生成的命令

ALTER INDEX [IX1] ON [TestDB].[dbo].[TEST_INDX] REBUILD WITH (SORT_IN_TEMPDB = OFF, ONLINE = ON, RESUMABLE = OFF)

保留壓縮

name    data_compression_desc
IX1 PAGE

使用維護計劃測試重建(我強烈主張 ola 的解決方案)

重建索引

在此處輸入圖像描述

選擇測試台

在此處輸入圖像描述

添加一些測試碎片級別。

在此處輸入圖像描述

插入一些值以使碎片繼續進行

INSERT INTO dbo.TEST_INDX(id)
SELECT id from TEST_INDX
go 4

檢查碎片百分比

SELECT 
I.[name] AS  INDX ,
IPS.avg_fragmentation_in_percent,
IPS.page_count
FROM sys.dm_db_index_physical_stats (DB_ID(), object_id('[dbo].[TEST_INDX]'), NULL, NULL, NULL) AS IPS
INNER JOIN sys.indexes AS I ON I.[object_id] = IPS.[object_id]
AND IPS.index_id = I.index_id
WHERE IPS.database_id = DB_ID()
and I.name = 'IX1'

結果

INDX    avg_fragmentation_in_percent    page_count
IX1 66,6666666666667    3

執行計劃

在此處輸入圖像描述

在查看計劃報告時,有趣的部分是該DATA_COMPRESSION = PAGE選項已添加到生成的REBUILD命令中!

Command:USE [TestDB]
GO
ALTER INDEX [IX1] ON [dbo].[TEST_INDX] REBUILD PARTITION = ALL WITH (PAD_INDEX = ON, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, RESUMABLE = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80, DATA_COMPRESSION = PAGE)

分片:

INDX    avg_fragmentation_in_percent    page_count
IX1 0   2

壓縮:

name    data_compression_desc
IX1 PAGE

引用自:https://dba.stackexchange.com/questions/226685