RCSI和索引维护

nkd*_*joe 5 sql-server isolation-level snapshot-isolation sql-server-2014 index-maintenance

我有一个启用了 RCSI 的数据库,并且从我记事起,我就一直在在线重建索引(SQL 2014 Enterprise)。我的理解是,如果我们要离线重建索引,我们将丢失额外的 14 个字节。但是,只要我们继续在线重建或重组,我们就会保留每行 14 个字节。那是对的吗?

Jos*_*ell 8

但是,只要我们继续在线重建或重组,我们就会保留每行 14 个字节。那是对的吗?

这是真的。 REBUILD WITH (ONLINE = ON)REORGANIZE将离开的14个字节原样。正常REBUILD会清除它。

如果禁用 RCSI,14 字节版本标记将被您提到的三个操作中的任何一个清除:

  • REBUILD
  • REBUILD WITH (ONLINE = ON)
  • REORGANIZE

为了您将来的参考,您自己进行测试并不太难。只需创建一个数据库和表,然后尝试不同的操作,每次检查行大小。

USE [master];
GO
CREATE DATABASE AreSeaEssEye;
GO

USE [AreSeaEssEye];
GO

CREATE TABLE dbo.Foo (c1 INT NOT NULL);
INSERT INTO dbo.Foo (c1) VALUES (1);

ALTER TABLE dbo.Foo ADD CONSTRAINT PK_Foo PRIMARY KEY (c1);
-- Baseline (11)
select max_record_size_in_bytes from sys.dm_db_index_physical_stats (db_id('AreSeaEssEye'), object_id('AreSeaEssEye.dbo.Foo'), null, null, 'DETAILED');

ALTER DATABASE AreSeaEssEye SET ALLOW_SNAPSHOT_ISOLATION ON;
UPDATE dbo.Foo SET c1 = 2;
-- After enabling RCSI and updating (25)
select max_record_size_in_bytes from sys.dm_db_index_physical_stats (db_id('AreSeaEssEye'), object_id('AreSeaEssEye.dbo.Foo'), null, null, 'DETAILED');

ALTER INDEX PK_Foo ON dbo.Foo REBUILD WITH (ONLINE = ON);
-- After online rebuild (still 25)
select max_record_size_in_bytes from sys.dm_db_index_physical_stats (db_id('AreSeaEssEye'), object_id('AreSeaEssEye.dbo.Foo'), null, null, 'DETAILED');

ALTER INDEX PK_Foo ON dbo.Foo REORGANIZE;
-- After reorg (still 25)
select max_record_size_in_bytes from sys.dm_db_index_physical_stats (db_id('AreSeaEssEye'), object_id('AreSeaEssEye.dbo.Foo'), null, null, 'DETAILED');

ALTER INDEX PK_Foo ON dbo.Foo REBUILD;
-- After normal rebuild (back to 11)
select max_record_size_in_bytes from sys.dm_db_index_physical_stats (db_id('AreSeaEssEye'), object_id('AreSeaEssEye.dbo.Foo'), null, null, 'DETAILED');
Run Code Online (Sandbox Code Playgroud)

结果呢?正如预期的那样:

RCSI 行版本更改的屏幕截图