Ketika Anda mengubah kolom menjadi TIDAK NULL, SQL Server harus menyentuh setiap halaman, bahkan jika tidak ada nilai NULL. Bergantung pada faktor pengisian Anda, ini sebenarnya dapat menyebabkan banyak pemisahan halaman. Setiap halaman yang disentuh, tentu saja, harus dicatat, dan saya curiga karena perpecahan itu dua perubahan mungkin harus dicatat untuk banyak halaman. Karena semuanya dilakukan dalam satu pass, log harus memperhitungkan semua perubahan sehingga, jika Anda menekan cancel, ia tahu persis apa yang harus diurungkan.
Sebuah contoh. Meja sederhana:
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
Sekarang, mari kita lihat detail halaman. Pertama-tama kita perlu mencari tahu halaman apa dan DB_ID yang sedang kita hadapi. Dalam kasus saya, saya membuat database bernama foo
, dan DB_ID kebetulan 5.
DBCC TRACEON(3604, -1);
DBCC IND('foo', 'dbo.floob', 1);
SELECT DB_ID();
Keluaran menunjukkan bahwa saya tertarik pada halaman 159 (satu-satunya baris dalam DBCC IND
keluaran dengan PageType = 1
).
Sekarang, mari kita lihat beberapa detail halaman terpilih saat kita melangkah melalui skenario 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);
Sekarang, saya tidak memiliki semua jawaban untuk ini, karena saya bukan orang internal yang dalam. Tetapi jelas bahwa - walaupun operasi pembaruan dan penambahan batasan NOT NULL tidak dapat disangkal menulis ke halaman - yang terakhir melakukannya dengan cara yang sama sekali berbeda. Tampaknya benar-benar mengubah struktur catatan, daripada hanya mengutak-atik bit, dengan menukar kolom nullable untuk kolom non-nullable. Mengapa harus melakukan itu, saya tidak yakin - pertanyaan yang bagus untuk tim mesin penyimpanan , saya kira. Saya percaya bahwa SQL Server 2012 menangani beberapa skenario ini jauh lebih baik, FWIW - tapi saya belum melakukan pengujian lengkap.
NOT NULL
kolom dengan default sebagai operasi metadata. Lihat juga "Menambahkan TIDAK NULL Kolom sebagai Operasi Online" di dokumentasi .