Điều đầu tiên trước tiên: Có bao nhiêu dữ liệu trong bảng? Số lượng hàng và kích thước của bảng?
Thứ hai: Bạn có thể sao lưu và khôi phục bảng này vào máy chủ thử nghiệm và chạy câu lệnh thay đổi để xem tác động (giả sử nó không khả thi do bảng quá lớn để phù hợp với hệ thống không sản xuất)? Tôi luôn thấy rằng thử nghiệm trong môi trường của mình chính xác hơn lời khuyên từ các interweb vì có một số yếu tố có thể ảnh hưởng đến kết quả có thể không được cung cấp trong câu hỏi chỉ vì không biết rằng những yếu tố đó có thể ảnh hưởng đến kết quả.
Thứ ba: tăng kích thước của trường có độ dài thay đổi là (giả sử bạn không vượt quá giới hạn 8060 byte) một thao tác dữ liệu meta đơn giản do không có dữ liệu thực tế nào sẽ thay đổi cho hoạt động đó. Mặt khác, NHƯNG, việc giảm kích thước của trường có độ dài thay đổi, thậm chí với thứ gì đó rõ ràng hơn sẽ hoạt động, không phải là thay đổi dữ liệu meta đơn giản vì SQL Server không biết, trước khi quét tất cả các hàng , rằng kích thước mới được yêu cầu là hợp lệ.
Do đó: Có, điều này sẽ khóa bảng trong một khoảng thời gian . Bao nhiêu thời gian Vâng, đây là bài kiểm tra mà tôi vừa làm:
Tôi đã có, từ một số thử nghiệm khác, một bảng có một INT NOT NULL
trường duy nhất và 1 triệu hàng. Tôi đã sao chép nó vào một bảng mới với mục đích thực hiện bài kiểm tra này thông qua:
SELECT *, CONVERT(NVARCHAR(MAX), NEWID()) AS [StringField]
INTO dbo.ResizeTest
FROM dbo.ClusteredUnique;
Bằng cách này, tôi đã bắt đầu với một kịch bản tương tự là có một MAX
lĩnh vực (tôi chỉ nhận ra rằng bạn có VARCHAR
và tôi đang sử dụng NVARCHAR
, nhưng điều đó không làm thay đổi hành vi tôi đang thấy) mà sau đó tôi có thể thay đổi 500
. Và nó có dữ liệu trong đó có thể dễ dàng chứa trong vòng 500 ký tự. Điều đó mất một vài phút.
Sau đó tôi chạy:
ALTER TABLE dbo.ResizeTest ALTER COLUMN [StringField] NVARCHAR(500) NULL;
Và điều đó chỉ mất hơn 11 phút.
Tôi vừa chạy lại bài kiểm tra một lần nữa, lần này là bỏ cái [ResizeTest]
bàn xuống và thay đổi cả hai NVARCHAR
để trở nên công bằng VARCHAR
, chỉ để chắc chắn rằng tôi đang so sánh táo với thứ gì đó ít nhất trông giống như một quả táo ;-).
Việc tạo bảng ban đầu mất 20 giây trong khi ALTER TABLE
mất 2 phút.
Vì vậy, về mặt ước tính thời gian chết, điều đó thực sự khó thực hiện vì nó dựa trên tốc độ I / O của đĩa, cho dù có hay không bất kỳ hoạt động tăng trưởng tự động nào cần phải xảy ra trên tệp dữ liệu và / hoặc nhật ký giao dịch, v.v. có lẽ là một phần lớn lý do tại sao thử nghiệm đầu tiên của tôi mất 11 phút để thay đổi và lần thứ hai, thậm chí với VARCHAR
một nửa kích thước của NVARCHAR
dữ liệu, chỉ mất 2 phút (tức là các tệp đã được phát triển trước tại thời điểm đó). Tuy nhiên, bạn nên nhớ rằng bài kiểm tra của tôi đang chạy trên máy tính xách tay của tôi không phải là đĩa nhanh nhất, nhưng nó cũng chỉ là 1 triệu hàng gồm 2 cột nhỏ (22 hoặc hơn byte mỗi hàng).
Và vì bạn đã hỏi nó sẽ làm gì với các trang dữ liệu, đây là câu trả lời của bạn. Tôi đã làm một sp_spaceused
sau khi tạo bảng, sau khi làm ALTER COLUMN
và sau khi làm ALTER TABLE dbo.ResizeTest REBUILD;
. Kết quả (các số sau được dựa trên thử nghiệm thứ hai bằng cách sử dụng VARCHAR
, không phải thử nghiệm đầu tiên sử dụng NVARCHAR
):
After initial table creation: 526,344 KB
After ALTER COLUMN VARCHAR(500): 1,031,688 KB <--- !! Yikes!!
After ALTER REBUILD: 526,472 KB
Nếu bạn lo lắng về việc cần phải duy trì hoạt động trong thời gian ngắn nhất có thể, hãy xem một bài viết mà tôi đã viết về việc đó: Tái cấu trúc 100 triệu hàng (hoặc nhiều hơn) Bảng trong giây. SRSLY! (yêu cầu đăng ký miễn phí).
ALTER
từng cột liên tiếp - mỗi hành động mất ít hơn một giây. Vào thời điểm chúng được thực hiện, bảng đã tăng gấp đôi kích thước, nhưng một khi tôi đã thực hiệnREBUILD
(cũng là thao tác phụ thứ hai), bảng trở lại kích thước ban đầu.