Kami memiliki tabel dengan baris 2.3B di dalamnya. Kami ingin mengubah kolom dari NOT NULL ke NULL. Kolom terkandung dalam satu indeks (bukan indeks berkerumun atau indeks PK). Tipe data tidak berubah (ini adalah INT). Hanya nullability. Pernyataan tersebut adalah sebagai berikut:
Alter Table dbo.Workflow Alter Column LineId Int NULL
Operasi membutuhkan lebih dari 10 sebelum kita menghentikannya (kita bahkan belum membiarkannya berjalan sampai selesai karena ini adalah operasi pemblokiran dan terlalu lama). Kami mungkin akan menyalin tabel ke server dev tes berapa lama sebenarnya dibutuhkan. Tapi, saya ingin tahu apakah ada yang tahu apa yang dilakukan SQL Server di bawah tenda ketika mengkonversi dari NOT NULL ke NULL? Juga, akankah indeks yang terpengaruh perlu dibangun kembali? Paket kueri yang dihasilkan tidak menunjukkan apa yang terjadi.
Tabel tersebut dikelompokkan (bukan tumpukan).
sumber
Jawaban:
Seperti disinggung oleh @Souplex di komentar satu penjelasan yang mungkin terjadi jika kolom ini adalah kolom pertama
NULL
dalam indeks non clustered yang diikutinya.Untuk pengaturan berikut
sys.dm_db_index_physical_stats menunjukkan indeks non-cluster
ix
memiliki 248 halaman daun dan satu halaman root.Seperti baris biasa di halaman daun indeks
Dan di halaman root
Lalu berlari ...
Kembali
Memeriksa kembali daun indeks, baris sekarang terlihat seperti
dan baris di halaman tingkat atas seperti di bawah ini.
Setiap baris telah diperbarui dan sekarang berisi dua byte untuk jumlah kolom bersama dengan byte lain untuk NULL_BITMAP.
Karena lebar baris tambahan indeks non-cluster sekarang memiliki 285 halaman daun dan sekarang dua halaman tingkat menengah bersama dengan halaman root.
Rencana eksekusi untuk
terlihat sebagai berikut
Ini menciptakan salinan baru indeks daripada memperbarui yang sudah ada dan perlu untuk membagi halaman.
sumber
Ini pasti akan membuat kembali indeks yang tidak berkerumun dan tidak hanya memperbarui metadata. Ini diuji pada SQL 2014 dan harus benar-benar tidak diuji pada sistem produksi:
Dan sekarang untuk bagian yang menyenangkan:
Ini akan memberi kita halaman basis data tempat tabel dan indeks yang tidak dikelompokkan disimpan.
Temukan
PagePID
dimanaIndexID
2 danPageType
2, lalu lakukan hal berikut:lalu:
Perhatikan bahwa ada bitmap nol di header:
Sekarang mari kita lakukan:
Jika Anda benar-benar tidak sabar, Anda dapat mencoba menjalankan
dbcc page
perintah lagi tetapi itu akan gagal, jadi mari kita periksa alokasi lagi denganDBCC IND (0, z, -1)
. Halaman itu akan bergerak seolah-olah dengan sihir.Jadi mengubah nullability kolom akan memengaruhi penyimpanan indeks non-cluster yang mencakup kolom itu, karena metadata perlu diperbarui dan Anda tidak perlu membangun kembali indeks setelahnya.
Banyak
ALTER TABLE ... ALTER COLUMN ...
operasi dapat dilakukanONLINE
dimulai dengan SQL Server 2016, tetapi:sumber