Mat*_*les 4 alter-table azure-sql-database transaction-log
我正在运行一个更改表,更改包含近 3000 万行的表上的列,SQL Azure 在大约 18 分钟后失败,说 The session has been terminated because of excessive transaction log space usage. Try modifying fewer rows in a single transaction.
我猜不可能将其分解为一次修改更少的行,所以我想知道对数据库进行此更改的选项是什么。SQL Azure 不允许我更改事务日志的大小(限制为 1GB)。
我猜我最好的办法是创建一个具有新布局的新表,将数据迁移到该表中,删除原始表,然后重命名新表以匹配旧表的名称。如果是这种情况,如何最好地构建这些命令?
我们系统的计划停机时间目前不是问题,因此此操作可以根据需要进行。
您需要将数据加载到新表中,以小批量方式执行此操作,然后删除现有表。我使用 AdventureWorks 中的 Sales.Customer 表整理了一个快速示例,类似的东西也适用于您。
首先,创建新表,并使用要使用的新数据类型完成:
CREATE TABLE [Sales].[Currency_New](
[CurrencyCode] [nchar](4) NOT NULL,
[Name] [varchar](128) NOT NULL,
[ModifiedDate] [datetime] NOT NULL,
CONSTRAINT [PK_Currency_New_CurrencyCode] PRIMARY KEY CLUSTERED
(
[CurrencyCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
Run Code Online (Sandbox Code Playgroud)
然后,插入您的记录并定义您的批次。我在这里使用 10,但您可能想要使用更大的数据,比如一次 10,000 行。对于 30MM 行,我什至建议您一次使用 100k 行批处理大小,这是我通常用于较大表的限制:
DECLARE @RowsInserted INT, @InsertVolume INT
SET @RowsInserted = 1
SET @InsertVolume = 10 --Set to # of rows
WHILE @RowsInserted > 0
BEGIN
INSERT INTO [Sales].[Currency_New] ([CurrencyCode]
,[Name]
,[ModifiedDate])
SELECT TOP (@InsertVolume)
SC.[CurrencyCode]
,SC.[Name]
,SC.[ModifiedDate]
FROM [Sales].[Currency] AS SC
LEFT JOIN [Sales].[Currency_New] AS SCN
ON SC.[CurrencyCode] = SCN.[CurrencyCode]
WHERE SCN.[CurrencyCode] IS NULL
SET @RowsInserted = @@ROWCOUNT
END
Run Code Online (Sandbox Code Playgroud)
在清理之前,我通常会进行完整性检查并验证行数是否相同:
SELECT COUNT(*) FROM [Sales].[Currency]
SELECT COUNT(*) FROM [Sales].[Currency_New]
Run Code Online (Sandbox Code Playgroud)
一旦您确信已经迁移了数据,就可以删除原始表:
DROP TABLE [Sales].[Currency]
Run Code Online (Sandbox Code Playgroud)
最后一步,重命名新表,这样用户就不必更改任何代码:
EXEC sp_rename '[Sales].[Currency_New]', '[Sales].[Currency]';
GO
Run Code Online (Sandbox Code Playgroud)
我不知道这需要多久。当您有一个清晰的维护窗口并且用户未连接时,我建议您尝试这样做。
HTH
归档时间: |
|
查看次数: |
6819 次 |
最近记录: |