SQL Server压缩索引是否在未指定数据压缩的情况下在重建时仍保持压缩状态?


Answers:


22

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

创建表和压缩索引

 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删除和创建索引时,如果不适应索引创建脚本,压缩定义也将丢失。

为什么?

因为在编写Index create语句时不会保留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;

结果

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

当我发现我压缩的3个数据库都失去了压缩并且不得不重新应用它时,我遇到了您。作为该工作的一部分,我测试并确认了您的结果,但不知道如何发生。我遇到的唯一其他可能性是,如果禁用索引,则它们在重建时会失去压缩。根据我们的ETL团队,情况似乎并非如此。我还在SQLServerCentral上提出了这个问题:sqlservercentral.com/Forums/2017336/Databases-Lost-Compression完全不知如何发生。
Marvel

嗨@Marvel,可能是其他进程在数据库上重新创建了索引吗?例如,某些应用程序在它们删除并创建无数索引的地方进行“升级”。但是,我认为没有更多细节,任何人都无法给出明确的解释。下次发生时,您可以找到索引创建日期,并找到它们是否在哪里重新创建(例如,通过此链接中的查询:stackoverflow.com/questions/7579932/…。否则,您总是可以提出问题,但是我可以认为你需要提供更多的信息。
兰迪Vertongen

1
谢谢,兰迪!我在数据库上设置了SCHEMA_OBJECT_CHANGE_GROUP审核,但这绝对可以帮助我更快地解析日志。我已经找到了罪魁祸首之一,即数据库的所有者,要求压缩的那个人一直在不断修改表和索引。他没有意识到,当他创建新表并在其中移动旧数据并创建新索引时,会导致压缩丢失。:(我为他提供了创建表和索引的正确方法。但是我不认为他是唯一的罪魁祸首。我无法想象他对e做到了这一点
Marvel
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.