我有一個擁有〜40 000 000行的數據庫表。我想爲此表添加一個標識列。如何以對數友好的方式做到這一點?如何將標識列添加到具有大量行的現有數據庫表中
當我做到以下幾點:
ALTER TABLE table_1
ADD id INT IDENTITY
這只是填補了整個日誌空間。
有沒有辦法以對數友好的方式做到這一點?該數據庫在SQL Server 2008上。
謝謝, Mohan。
我有一個擁有〜40 000 000行的數據庫表。我想爲此表添加一個標識列。如何以對數友好的方式做到這一點?如何將標識列添加到具有大量行的現有數據庫表中
當我做到以下幾點:
ALTER TABLE table_1
ADD id INT IDENTITY
這只是填補了整個日誌空間。
有沒有辦法以對數友好的方式做到這一點?該數據庫在SQL Server 2008上。
謝謝, Mohan。
整體過程可能會慢得多,整體鎖定開銷較大,但如果您只關心事務日誌大小,則可以嘗試以下操作。
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 ;
您是否有時間可以將dataqbase置於單用戶模式?最好在單用戶模式下執行此操作,並且除dba外的所有用戶均被鎖定。 – HLGEM
有與現有的數據相加標識列一個表的方法有兩種:
創建標識新表,將數據複製到這個新表然後刪除現有表,然後重命名臨時表。
創建標識的新列&刪除現有列
參考:http://cavemansblog.wordpress.com/2009/04/02/sql-how-to-add-an-identity-column-to-a-table-with-data/
我只是這樣做是爲了我的表有2700行。轉到表的設計,添加新列,將其設置爲不允許空值,將列設置爲列屬性中的標識列,並且應該這樣做。我簡直就是在不到5分鐘的時間內完成了這個工作,而且它對我很有幫助。如果這回答你的問題,請選擇答案。
這是MySQL,SQL Server,PostGres,Oracle嗎? – JNK
禁用日誌,添加列,啓用日誌。 –
這不應該是一個答案,而不僅僅是一個評論? –