Tingkatkan kolom pengubah kecepatan pada tabel besar menjadi NON NULL

12

Saya baru-baru ini menambahkan kolom bit yang bisa NULL ke tabel yang memiliki hampir 500 juta baris. Tidak ada default pada kolom, namun semua sisipan menentukan nilai 0 atau 1, dan saya menjalankan rutin satu kali untuk menetapkan 0 atau 1 ke semua baris yang ada (memperbarui baris dalam batch kecil). Setiap baris sekarang harus memiliki 0 atau 1 di kolom itu.

Saya ingin membuat kolom bit non-nullable tetapi ketika saya mencoba melakukannya melalui ALTER TABLE t1 ALTER COLUMN c1 bit not null, itu mulai berjalan selama 3 menit dan saya menghentikannya karena itu memblokir semua bacaan ke meja dan saya menduga itu akan memakan waktu lama untuk menyelesaikannya. . Mungkin saja tidak akan terlalu lama, tetapi saya tidak bisa mengambil risiko terlalu banyak tidak tersedianya. Kembalikan itu sendiri membutuhkan waktu 6 menit.

Apakah Anda memiliki saran tentang bagaimana saya dapat membuat kolom tidak dapat dibatalkan tanpa perlu waktu berjam-jam untuk menyelesaikannya? Selain itu, adakah cara untuk memperkirakan berapa lama ALTER TABLE ALTER COLUMNpernyataan yang saya mulai dan kemudian batalkan akan selesai?

Saya menggunakan SQL Server 2017 Web Edition.

Ben Amada
sumber

Jawaban:

12

Alih-alih mengubah definisi kolom Anda bisa menambahkan CHECK CONSTRAINTyang tidak memungkinkan NULL untuk kolom itu. Tabel masih perlu dipindai tetapi tidak perlu memodifikasi setiap halaman data tunggal, jadi itu harus menjadi operasi yang jauh lebih cepat. Sayangnya, kunci Sch-M masih akan ditahan selama operasi. Salah satu triknya adalah mencoba memasukkan tabel sebanyak mungkin ke buffer pool sebelum mencoba menambahkan kendala. Itu dapat mengurangi jumlah waktu kunci Sch-M ditahan.

Anda kemudian dapat menghapus batasan dan mengubah definisi kolom selama jendela perawatan Anda berikutnya.

Joe Obbish
sumber
Terima kasih Joe untuk idenya. Saya hampir pergi dengan menambahkan batasan pemeriksaan tetapi memiliki jendela pemeliharaan selama akhir pekan dan mampu mengubah kolom menjadi non-nullable. Saya tidak yakin apakah itu membantu, tetapi untuk mencoba dan mendapatkan data tabel ke dalam buffer pool, tepat sebelum membuat kolom tidak dapat dibatalkan, saya berlari SELECT c1, count(*) FROM t1 GROUP BY c1yang membutuhkan waktu sekitar 9 menit untuk berjalan. ALTER TABLE ALTER COLUMNPernyataan aktual setelah itu membutuhkan 25 menit untuk selesai. Lumayan.
Ben Amada
11

Jika Anda menggunakan Enterprise Edition (EE), strategi yang lebih baik mungkin adalah menambahkannya NOT NULLdengan default 0atau 1(mana yang paling umum).

Ini adalah perubahan metadata-satunya dalam EE . Kemudian perbarui yang perlu dibalik. Ini berarti lebih sedikit pembaruan dan tidak perlu mengubah kolom nullability ketika selesai. - martin-smith

pengguna126897
sumber
Menariknya saya memperhatikan fitur ini minggu lalu ketika saya menguji menambahkan kolom bit yang tidak dapat dibatalkan dengan nilai default ke tabel besar yang sama ini di mesin lokal saya yang menjalankan edisi pengembang SQL - kolom ditambahkan secara instan dan saya tidak tahu mengapa . Belakangan dia mengatakan bahwa itu pasti karena edisi pengembang menyertakan fitur EE.
Ben Amada
-3

Coba salin data ke tabel baru, lalu ganti namanya. Anda harus mengurus semua kendala dan indeks. Itulah yang dilakukan perancang tabel SSMS saat Anda ingin menyusun ulang kolom (misalnya), tetapi Anda harus memeriksa skrip untuk melihat apakah ada sesuatu yang tidak beres.

Selama penyalinan, akses baca ke tabel sumber bukan masalah, tetapi jika ada penulisan, mereka mungkin diblokir atau tidak disalin, tergantung pada tingkat isolasi.

Razvan Socol
sumber