Cách duy nhất lành mạnh để cập nhật một bảng gồm 120 triệu bản ghi là sử dụng SELECT
câu lệnh điền giây bàn. Bạn phải cẩn thận khi làm điều này. Hướng dẫn bên dưới.
Trường hợp đơn giản
Đối với một bảng có chỉ mục được phân nhóm, trong thời gian sử dụng DML đồng thời:
-
SELECT *, new_col = 1 INTO clone.BaseTable FROM dbo.BaseTable
- tạo lại các chỉ mục, ràng buộc, v.v. trên bảng mới
- chuyển đổi cũ và mới w / ALTER SCHEMA ... CHUYỂN.
- bỏ bảng cũ
Nếu bạn không thể tạo một lược đồ sao chép, một tên bảng khác trong cùng một lược đồ sẽ làm được. Hãy nhớ đổi tên tất cả các ràng buộc và trình kích hoạt của bạn (nếu có) sau khi chuyển đổi.
Trường hợp không đơn giản
Đầu tiên, hãy tạo lại BaseTable
của bạn có cùng tên dưới một lược đồ khác, ví dụ:clone.BaseTable
. Sử dụng một lược đồ riêng biệt sẽ đơn giản hóa quá trình đổi tên sau này.
- Bao gồm chỉ mục được nhóm , nếu có. Hãy nhớ rằng các khóa chính và các ràng buộc duy nhất có thể được nhóm lại, nhưng không nhất thiết phải như vậy.
- Bao gồm các cột nhận dạng và cột được tính toán , nếu có.
- Bao gồm cột INT mới của bạn , bất cứ nơi đâu.
- Không bao gồm bất kỳ điều nào sau đây:
- trình kích hoạt
- ràng buộc khóa ngoại
- chỉ mục không phân cụm / khóa chính / ràng buộc duy nhất
- kiểm tra các ràng buộc hoặc ràng buộc mặc định. Giá trị mặc định không tạo ra nhiều khác biệt, nhưng chúng tôi đang cố gắng giữ mọi thứ ở mức tối thiểu.
Sau đó, kiểm tra chèn của bạn với w / 1000 hàng:
-- assuming an IDENTITY column in BaseTable
SET IDENTITY_INSERT clone.BaseTable ON
GO
INSERT clone.BaseTable WITH (TABLOCK) (Col1, Col2, Col3)
SELECT TOP 1000 Col1, Col2, Col3 = -1
FROM dbo.BaseTable
GO
SET IDENTITY_INSERT clone.BaseTable OFF
Kiểm tra kết quả. Nếu mọi thứ xuất hiện theo thứ tự:
- cắt ngắn bảng sao chép
- đảm bảo rằng cơ sở dữ liệu trong mô hình khôi phục được ghi nhật ký hàng loạt hoặc đơn giản
- thực hiện việc chèn đầy đủ.
Quá trình này sẽ mất một lúc, nhưng không lâu bằng bản cập nhật. Sau khi hoàn tất, hãy kiểm tra dữ liệu trong bảng sao chép để đảm bảo rằng mọi thứ đều chính xác.
Sau đó, tạo lại tất cả các khóa chính không phân cụm / các ràng buộc / chỉ mục duy nhất và các ràng buộc khóa ngoại (theo thứ tự đó). Tạo lại mặc định và kiểm tra các ràng buộc, nếu có. Tạo lại tất cả các trình kích hoạt. Tạo lại từng ràng buộc, chỉ mục hoặc trình kích hoạt trong một lô riêng biệt. ví dụ:
ALTER TABLE clone.BaseTable ADD CONSTRAINT UQ_BaseTable UNIQUE (Col2)
GO
-- next constraint/index/trigger definition here
Cuối cùng, di chuyển dbo.BaseTable
vào một lược đồ dự phòng và clone.BaseTable
vào lược đồ dbo (hoặc bất cứ nơi nào bảng của bạn được cho là tồn tại).
-- -- perform first true-up operation here, if necessary
-- EXEC clone.BaseTable_TrueUp
-- GO
-- -- create a backup schema, if necessary
-- CREATE SCHEMA backup_20100914
-- GO
BEGIN TRY
BEGIN TRANSACTION
ALTER SCHEMA backup_20100914 TRANSFER dbo.BaseTable
-- -- perform second true-up operation here, if necessary
-- EXEC clone.BaseTable_TrueUp
ALTER SCHEMA dbo TRANSFER clone.BaseTable
COMMIT TRANSACTION
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() -- add more info here if necessary
ROLLBACK TRANSACTION
END CATCH
GO
Nếu bạn cần giải phóng dung lượng ổ đĩa, bạn có thể xóa bảng gốc của mình tại thời điểm này, mặc dù có thể thận trọng nếu giữ nó lâu hơn.
Không cần phải nói, đây lý tưởng là một ngoại tuyến hoạt động. Nếu bạn có người sửa đổi dữ liệu trong khi bạn thực hiện thao tác này, bạn sẽ phải thực hiện thao tác xác thực với chuyển đổi lược đồ. Tôi khuyên bạn nên tạo trình kích hoạt trên dbo.BaseTable
để ghi tất cả DML vào một bảng riêng biệt. Kích hoạt trình kích hoạt này trước khi bạn bắt đầu chèn. Sau đó, trong cùng một giao dịch mà bạn thực hiện chuyển giản đồ, hãy sử dụng bảng nhật ký để thực hiện xác thực. Kiểm tra điều này đầu tiên trên một tập hợp con của dữ liệu! Dây đai rất dễ vặn.