Moh*_*han 6 sql sql-server identity sql-server-2008
我有一个数据库表,有~40 000 000行.我想在此表中添加一个标识列.如何以对数友好的方式做到这一点?
当我执行以下操作时:
ALTER TABLE table_1
ADD id INT IDENTITY
Run Code Online (Sandbox Code Playgroud)
这只会填满整个日志空间.
有没有办法以对数友好的方式做到这一点?该数据库位于SQL Server 2008上.
谢谢,莫汉.
由于整体锁定开销更大,整个过程可能会慢很多,但如果您只关心事务日志大小,您可以尝试以下操作。
ALTER TABLE ... ALTER COLUMN将该列标记为NOT NULL。这将需要锁定并扫描整个表以验证更改,但不需要太多日志记录。ALTER TABLE ... SWITCH使该列成为标识列。这只是元数据的更改。下面的示例代码
/*Set up test table with just one column*/
CREATE TABLE table_1 ( original_column INT )
INSERT INTO table_1
SELECT DISTINCT
number
FROM master..spt_values
/*Step 1 */
ALTER TABLE table_1 ADD id INT NULL
/*Step 2 */
DECLARE @Counter INT = 0 ,
@PrevCounter INT = -1
WHILE @PrevCounter <> @Counter
BEGIN
SET @PrevCounter = @Counter;
WITH T AS ( SELECT TOP 100
* ,
ROW_NUMBER() OVER ( ORDER BY @@SPID )
+ @Counter AS new_id
FROM table_1
WHERE id IS NULL
)
UPDATE T
SET id = new_id
SET @Counter = @Counter + @@ROWCOUNT
END
BEGIN TRY;
BEGIN TRANSACTION ;
/*Step 3 */
ALTER TABLE table_1 ALTER COLUMN id INT NOT NULL
/*Step 4 */
DECLARE @TableScript NVARCHAR(MAX) = '
CREATE TABLE dbo.Destination(
original_column INT,
id INT IDENTITY(' + CAST(@Counter + 1 AS VARCHAR) + ',1)
)
ALTER TABLE dbo.table_1 SWITCH TO dbo.Destination;
'
EXEC(@TableScript)
DROP TABLE table_1 ;
EXECUTE sp_rename N'dbo.Destination', N'table_1', 'OBJECT' ;
COMMIT TRANSACTION ;
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0
ROLLBACK TRANSACTION ;
PRINT ERROR_MESSAGE() ;
END CATCH ;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
20242 次 |
| 最近记录: |