Tại sao thêm một cột KHÔNG NULL với một ràng buộc mặc định ngay lập tức?


16
CREATE TABLE TestTab (ID INT IDENTITY(1,1), st nvarchar(100))

INSERT INTO TestTab (st) values ('a')
INSERT INTO TestTab (st) values ('b')
INSERT INTO TestTab (st) values ('c')
INSERT INTO TestTab (st) values ('d')
INSERT INTO TestTab (st) values ('e')

INSERT INTO TestTab (st) SELECT TOP 10000 st from testtab
GO 30

ALTER TABLE TestTab ADD newcol nvarchar(10) DEFAULT 'newcol'
UPDATE TestTab SET newcol = 'newcol'  --6 sec
ALTER TABLE TestTab ADD newcol1 nvarchar(10) DEFAULT 'newcol1' NOT NULL

DROP TABLE TestTab

Khi tôi thực hiện kịch bản thử nghiệm này, ALTERvới UPDATEmất 6 giây mà là điều dễ hiểu.

Tuy nhiên, ALTERvới các DEFAULT NOT NULLthực thi ngay lập tức ngay cả trên một bảng lớn hơn nhiều. Có bất kỳ lời giải thích về lý do tại sao điều này là tức thời? Trên đĩa vật lý, dữ liệu vẫn cần được ghi vào tất cả các hàng phải không?

Tôi đã thử xem xét SET STATISTICS IO ONvà kế hoạch Truy vấn, tuy nhiên những kế hoạch đó dường như không khả dụng cho các hoạt động DDL.

Câu trả lời:


23

Có, việc thêm một cột với KHÔNG NULL và mặc định không thực sự ghi các giá trị cho tất cả các hàng tại thời điểm thay đổi, do đó, nó không còn là thao tác kích thước dữ liệu nữa. Khi bạn chọn từ bảng, các cột thực sự được vật chất hóa từ sys.system_iternals_partition_columns , điều này ngăn tất cả các giá trị phải được ghi (cho đến khi chúng được thay đổi). Lưu ý rằng điều này không hoạt động đối với tất cả các loại dữ liệu và yêu cầu Phiên bản doanh nghiệp.

Remus Rusanu giải thích điều này chi tiết hơn ở đây:

Ngoài ra, đối ALTERvới ít nhất, chúng tôi vẫn không thể hiển thị cho bạn một kế hoạch vì SQL Server không tạo ra một kế hoạch, nhưng để xem I / O, bạn có thể sử dụng SQL Sentry Plan Explorer . * Ảnh chụp màn hình này hiển thị thêm một cột, c5 , "trực tuyến" như được mô tả ở trên và sau đó là một cột khác, c6, "ngoại tuyến" vì các loại LOB không được hỗ trợ. Bạn có thể thấy I / O chủ yếu được thể hiện dưới dạng đọc thay vì viết, nhưng điều đáng nói hơn là (không hợp lệ!) UPDATELiên quan đến các thay đổi ngoại tuyến.

I / O cho thay đổi trực tuyến so với ngoại tuyến

Nếu bạn không có Phiên bản doanh nghiệp, cả hai câu lệnh sẽ được UPDATEđính kèm phụ (và các lần đọc liên quan). (Và nếu bạn sử dụng phiên bản Plan Explorer miễn phí, không nhận được ngăn xếp cuộc gọi truy vấn đầy đủ, bạn sẽ không thấy ở trên - bạn sẽ chỉ thấy một cây câu lệnh trống. Yêu cầu phải có phiên bản trả phí để xem toàn bộ truy vấn gọi ngăn xếp.)

Lưu ý rằng SQL Server sẽ tạo ra một kế hoạch ước tính , nhưng nó không hữu ích lắm. Ở tất cả. Và kế hoạch ước tính cho một thay đổi trực tuyến giống hệt với kế hoạch ước tính cho một thay đổi ngoại tuyến.

Sơ đồ kế hoạch thay đổi trực tuyến

* Khước từ trách nhiệm: Tôi làm việc cho SQL Sentry.


4
+1: đặc biệt. cho "Phiên bản doanh nghiệp". Tôi đã luôn tự hỏi tại sao nó không hoạt động tại một số trang web của khách hàng của tôi ...
RBarryYoung
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.