构建新版本的表并通过重命名替换旧版本,这是一个好主意吗?

kry*_*tah 2 sql-server

我们有一个稍重的表,它半频繁地(每约 5 分钟)由程序重新创建。我想知道是否可以做些什么来最大限度地减少表重建期间的停机时间,并且到目前为止已经想到了两种可能性(让我们称表为“设备”):

选项 A
1) 在过程中创建新表,命名Device_new
2) 将旧表重命名DeviceDevice_old
3) 将新表重命名Device_newDevice

选项 B
与选项 A 相同,只是使用分区切换。
警告:分区切换的设置要复杂得多,并且对使用有相当严格的要求。

这些选项是否是糟糕的解决方案,如果是,您将如何解决此用例?谢谢你。

Dan*_*man 6

您提到分区切换更复杂,但当表未分区时情况并非如此。可以将SWITCH一个非分区表的全部内容有效地替换为另一个作为仅元数据操作的非分区表。要求SWITCH是源表和目标表必须具有相同的架构、索引、约束,并且存储对齐。这些要求可能与重命名技术相同,因此工作量是相似的。

请注意,与使用分区函数和方案的表分区不同,SWITCH未分区表可用于任何 SQL Server 版本。

下面是选项 B 的示例 DDL 脚本:

CREATE TABLE dbo.Device(
      DeviceID int NOT NULL
        CONSTRAINT PK_Device PRIMARY KEY CLUSTERED ON [PRIMARY]
    , DeviceName varchar(30) NOT NULL
    );
CREATE INDEX idx_Device_DeviceName ON dbo.Device(DeviceName) ON [PRIMARY];
GO

CREATE TABLE dbo.Device_new(
      DeviceID int NOT NULL
        CONSTRAINT PK_Device_new PRIMARY KEY CLUSTERED ON [PRIMARY]
    , DeviceName varchar(30) NOT NULL
    );
CREATE INDEX idx_Device_new_DeviceName ON dbo.Device_new(DeviceName) ON [PRIMARY];
GO

CREATE PROCEDURE dbo.RefreshDevice
AS

SET XACT_ABORT ON;

BEGIN TRY

    TRUNCATE TABLE dbo.Device_new;

    --load dbo.Device_new with new data here

    BEGIN TRAN;

    TRUNCATE TABLE dbo.Device;

    ALTER TABLE dbo.Device_new
        SWITCH TO dbo.Device;

    COMMIT;

END TRY
BEGIN CATCH

    IF @@TRANCOUNT > 0 ROLLBACK;

    THROW;

END CATCH;
GO
Run Code Online (Sandbox Code Playgroud)