SQL Server 压缩索引在重建时是否保持压缩状态而不指定数据压缩?

Pau*_*ole 15 index sql-server data-pages compression

使用页面压缩 ( ALTER INDEX IX1 REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE))重建其 SQL Server 索引后,后续重建(如某些维护脚本超过某个碎片阈值所做的那样)是否需要再次指定数据压缩?否则索引会被有效地解压吗?

Ran*_*gen 24

重建/重组索引时,索引保持压缩状态。

创建表和压缩索引

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

检查压缩

 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';
Run Code Online (Sandbox Code Playgroud)

结果

name    data_compression_desc
IX1     PAGE
Run Code Online (Sandbox Code Playgroud)

重建索引

ALTER INDEX IX1 on  DBO.TEST_INDX rebuild 
Run Code Online (Sandbox Code Playgroud)

检查压缩

 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'
Run Code Online (Sandbox Code Playgroud)

结果

name    data_compression_desc
IX1     PAGE
Run Code Online (Sandbox Code Playgroud)

禁用它们然后重建会产生不同的结果,因为禁用会删除索引,同时保留索引定义。

alter index IX1 on  DBO.TEST_INDX DISABLE ;
alter index IX1 on  DBO.TEST_INDX REBUILD ;
Run Code Online (Sandbox Code Playgroud)

结果

name    data_compression_desc
Run Code Online (Sandbox Code Playgroud)

压缩丢失,在不调整索引创建脚本的情况下通过 SSMS 删除和创建索引时,压缩定义也会丢失。

为什么?

因为在编写索引创建语句的脚本时不会保留 data_compression 选项。

但是,如果我们禁用 index ,则使用压缩重建,然后再次重建:

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;
Run Code Online (Sandbox Code Playgroud)

结果

name    data_compression_desc
IX1 PAGE
Run Code Online (Sandbox Code Playgroud)

使用 Ola Hallengren 的维护解决方案测试重建

为测试目的修改参数。

添加一些数据以到达一页,因为 MinNumberOfPages 参数需要它。

INSERT INTO dbo.TEST_INDX(id,bla)
VALUES(5,'test');
go 10 
Run Code Online (Sandbox Code Playgroud)

执行索引优化过程以打印出该语句。

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;
Run Code Online (Sandbox Code Playgroud)

结果:

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
Run Code Online (Sandbox Code Playgroud)

执行生成的命令

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

压缩保留

name    data_compression_desc
IX1 PAGE
Run Code Online (Sandbox Code Playgroud)

使用维护计划测试重建(我强烈支持 ola 的解决方案)

重建索引

在此处输入图片说明

选择测试表

在此处输入图片说明

添加一些测试碎片级别。

在此处输入图片说明

插入一些值以进行碎片化

INSERT INTO dbo.TEST_INDX(id)
SELECT id from TEST_INDX
go 4
Run Code Online (Sandbox Code Playgroud)

检查碎片百分比

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'
Run Code Online (Sandbox Code Playgroud)

结果

INDX    avg_fragmentation_in_percent    page_count
IX1 66,6666666666667    3
Run Code Online (Sandbox Code Playgroud)

运行计划

在此处输入图片说明

在查看计划报告时,这里有趣的部分是该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)
Run Code Online (Sandbox Code Playgroud)

碎片化:

INDX    avg_fragmentation_in_percent    page_count
IX1 0   2
Run Code Online (Sandbox Code Playgroud)

压缩:

name    data_compression_desc
IX1 PAGE
Run Code Online (Sandbox Code Playgroud)