Khi bạn thay đổi một cột thành KHÔNG NULL, SQL Server phải chạm vào từng trang, ngay cả khi không có giá trị NULL. Tùy thuộc vào yếu tố điền của bạn, điều này thực sự có thể dẫn đến rất nhiều phân chia trang. Tất cả các trang được chạm vào, tất nhiên, phải được ghi lại và tôi nghi ngờ do sự chia tách mà hai thay đổi có thể phải được ghi lại cho nhiều trang. Vì tất cả đã được thực hiện trong một lần duy nhất, tuy nhiên, nhật ký phải tính đến tất cả các thay đổi để nếu bạn nhấn hủy, nó sẽ biết chính xác những gì cần hoàn tác.
Một ví dụ. Bảng đơn giản:
DROP TABLE dbo.floob;
GO
CREATE TABLE dbo.floob
(
id INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
bar INT NULL
);
INSERT dbo.floob(bar) SELECT NULL UNION ALL SELECT 4 UNION ALL SELECT NULL;
ALTER TABLE dbo.floob ADD CONSTRAINT df DEFAULT(0) FOR bar
Bây giờ, hãy nhìn vào chi tiết trang. Đầu tiên chúng ta cần tìm hiểu trang nào và DB_ID chúng ta đang làm việc. Trong trường hợp của tôi, tôi đã tạo một cơ sở dữ liệu được gọi foo
và DB_ID là 5.
DBCC TRACEON(3604, -1);
DBCC IND('foo', 'dbo.floob', 1);
SELECT DB_ID();
Đầu ra chỉ ra rằng tôi quan tâm đến trang 159 (hàng duy nhất trong DBCC IND
đầu ra với PageType = 1
).
Bây giờ, hãy xem một số chi tiết trang được chọn khi chúng ta bước qua kịch bản của OP.
DBCC PAGE(5, 1, 159, 3);
UPDATE dbo.floob SET bar = 0 WHERE bar IS NULL;
DBCC PAGE(5, 1, 159, 3);
ALTER TABLE dbo.floob ALTER COLUMN bar INT NOT NULL;
DBCC PAGE(5, 1, 159, 3);
Bây giờ, tôi không có tất cả các câu trả lời cho điều này, vì tôi không phải là một người nội tâm sâu sắc. Nhưng rõ ràng rằng - trong khi cả hoạt động cập nhật và bổ sung ràng buộc KHÔNG NULL đều không thể phủ nhận ghi vào trang - thì điều này lại làm theo cách hoàn toàn khác. Nó dường như thực sự thay đổi cấu trúc của bản ghi, thay vì chỉ sử dụng bit, bằng cách hoán đổi cột nullable cho cột không null. Tại sao nó phải làm điều đó, tôi không chắc lắm - một câu hỏi hay cho nhóm công cụ lưu trữ , tôi đoán vậy. Tôi tin rằng SQL Server 2012 xử lý một số tình huống này tốt hơn rất nhiều, FWIW - nhưng tôi vẫn chưa thực hiện bất kỳ thử nghiệm toàn diện nào.
NOT NULL
cột với mặc định là hoạt động siêu dữ liệu. Đồng thời xem "Thêm các cột KHÔNG NULL dưới dạng một hoạt động trực tuyến" trong tài liệu .