当您将表 A 切换到表 B 时,索引数据是否也会切换?

kry*_*tah 8 sql-server sql-server-2014

我目前有一个相当大的表(5-7 百万行)。该表由一个过程定期重建,该过程在临时表中构建数据,然后使用该ALTER TABLE .. SWITCH TO ..语句将数据切换到生产表中。

例子:

BEGIN TRAN;

-- Rebuild indexes
ALTER INDEX IX_NC_GroupEvent_staging_GroupName on [dbo].[GroupEvent_staging]
   REBUILD;

ALTER INDEX IX_NC_GroupEvent_staging_Created ON [dbo].[GroupEvent_staging]
   REBUILD;

-- Empty production table
TRUNCATE TABLE [dbo].[GroupEvent];

-- Switch data from staging-table into production table
ALTER TABLE [dbo].[GroupEvent_staging] SWITCH TO [dbo].[GroupEvent]

COMMIT;
Run Code Online (Sandbox Code Playgroud)

执行此操作时,索引(或索引数据)的当前状态是否也会切换?我问是因为两个原因:

1) 为了执行SWITCH TO语句,要求源表和目标表必须包含相同的索引。这让我相信索引数据也可能会被切换,但我不知道如何验证这一点。
2)以这种方式构建表的主要好处是避免在使用生产表时对生产表执行过多的工作。当然,如果我能够在临时表上重建索引并将重建的索引与表一起切换到生产索引,那会让我感到非常高兴。

Mar*_*ith 6

索引数据也会被切换吗?

是的。如果不这样做会很奇怪,因为这样查询会返回错误的结果,或者我们将不得不在切换后手动重建索引。

我不知道如何验证这个

一种方法是尝试一下

CREATE TABLE [dbo].[GroupEvent]
  (
     GroupName VARCHAR(100) INDEX IX_NC_GroupEvent_staging_GroupName,
     Created   DATETIME INDEX IX_NC_GroupEvent_staging_Created 
  );

CREATE TABLE [dbo].[GroupEvent_staging]
  (
     GroupName VARCHAR(100) INDEX IX_NC_GroupEvent_staging_GroupName,
     Created   DATETIME INDEX IX_NC_GroupEvent_staging_Created 
  );

INSERT INTO [dbo].[GroupEvent_staging]
VALUES      ('Group1',GETDATE()),
            ('Group2',GETDATE());

ALTER INDEX IX_NC_GroupEvent_staging_GroupName ON [dbo].[GroupEvent_staging] REBUILD;

ALTER INDEX IX_NC_GroupEvent_staging_Created ON [dbo].[GroupEvent_staging] REBUILD;

SELECT index_id,
       allocated_page_file_id,
       allocated_page_page_id
FROM   sys.dm_db_database_page_allocations(DB_ID(), OBJECT_ID('[dbo].[GroupEvent_staging]'), NULL, NULL, 'DETAILED')
WHERE  is_allocated = 1; 

-- Empty production table
TRUNCATE TABLE [dbo].[GroupEvent];

-- Switch data from staging-table into production table
ALTER TABLE [dbo].[GroupEvent_staging] SWITCH TO [dbo].[GroupEvent];

SELECT index_id,
       allocated_page_file_id,
       allocated_page_page_id
FROM   sys.dm_db_database_page_allocations(DB_ID(), OBJECT_ID('[dbo].[GroupEvent]'), NULL, NULL, 'DETAILED')
WHERE  is_allocated = 1; 

SELECT GroupName
FROM   [dbo].[GroupEvent];

DROP TABLE [dbo].[GroupEvent], [dbo].[GroupEvent_staging]; 
Run Code Online (Sandbox Code Playgroud)

在返回两行的过程中访问的唯一对象是显示数据必须已切换的索引。

在此处输入图片说明

上面还将sys.dm_db_database_page_allocationsforGroupEvent_Staging切换前的结果与切换后的类似查询进行比较GroupEvent,以查看堆本身(index_id=0)和两个非聚集索引(ids 2 & 3)的页面保持不变。这表明切换是元数据,仅具有转移的分配页面的所有权。

在此处输入图片说明