it-swarm.asia

Menambahkan kolom ke tabel produksi

Apa cara terbaik untuk menambahkan kolom ke tabel produksi besar di SQL Server 2008 R2? Menurut buku-buku Microsoft online:

Perubahan yang ditentukan dalam ALTER TABLE diimplementasikan segera. Jika perubahan memerlukan modifikasi dari baris dalam tabel, ALTER TABLE memperbarui baris. ALTER TABLE memperoleh kunci skema modifikasi di atas meja untuk memastikan bahwa tidak ada koneksi lain referensi bahkan metadata untuk tabel selama perubahan, kecuali operasi indeks online yang membutuhkan kunci SCH-M sangat pendek di akhir.

(http://msdn.Microsoft.com/en-us/library/ms190273.aspx)

Di atas meja besar dengan jutaan baris, ini bisa memakan waktu cukup lama. Apakah mengambil pemadaman satu-satunya pilihan? Apa cara terbaik untuk menangani situasi seperti ini?

29
sh-beta

"Tergantung"

Jika Anda menambahkan kolom yang tidak memerlukan penambahan data ke baris, maka itu bisa sangat cepat.

Misalnya, menambahkan int atau char membutuhkan gerakan baris fisik. Menambahkan nullable varchar tanpa default seharusnya tidak (kecuali bitmap NULL perlu diperluas)

Anda perlu mencobanya pada salinan produksi yang dipulihkan untuk mendapatkan perkiraan

Membuat tabel baru, menyalin, mengganti nama mungkin membutuhkan waktu lebih lama jika Anda harus menambahkan kembali indeks dan kunci pada satu miliar tabel baris.

Saya telah mengubah miliar tabel baris yang membutuhkan waktu beberapa detik untuk menambahkan kolom yang dapat dibatalkan.

Apakah saya mengatakan untuk mengambil cadangan terlebih dahulu?

27
gbn

Jika kolom NULLable, dampaknya harus diabaikan. Jika kolom tidak bisa NULL dan nilainya harus ditetapkan, maka itu bisa sangat berbeda. Apa yang akan saya lakukan dalam kasus ini adalah, alih-alih menambahkan batasan tidak nol dan standar dalam satu kesempatan, secara efektif menambahkan data ke setiap baris:

  • tambahkan kolom sebagai NULLable - harus cepat dalam banyak kasus
  • perbarui nilai ke default
    • anda dapat melakukan ini dalam batch jika perlu
    • anda juga dapat menggunakan ini untuk menerapkan logika kondisional di mana beberapa baris mungkin tidak mendapatkan default
  • tambahkan batasan tidak nol/standar
    • ini akan lebih cepat ketika tidak ada data yang NULL, tetapi masih harus diukur

Setuju dengan @gbn bahwa Anda dapat menguji ini dengan mengembalikan salinan produksi dan mencobanya di sana ... Anda akan mendapatkan ide yang bagus tentang waktu (dengan asumsi perangkat keras agak mirip) dan Anda juga dapat melihat dampaknya pada log transaksi.

21
Aaron Bertrand

Sudahkah Anda mempertimbangkan:

  1. Membuat tabel baru yang menyertakan perubahan definisi tabel.
  2. Memasukkan ke dalam definisi tabel baru memilih dari tabel asli.
  3. Mengganti nama tabel asli menjadi _orig dan kemudian mengubah nama tabel baru ke nama tabel asli.

Kerugiannya di sini adalah Anda harus memiliki ruang yang cukup dalam database untuk melakukan perubahan ini. Anda mungkin masih memerlukan kunci baca di atas meja untuk mencegah pembacaan yang kotor.

Namun, Anda meminimalkan dampaknya kepada pengguna akhir jika ada kesempatan atau kebutuhan untuk tabel asli untuk diakses secara bersamaan. Ini juga harus meminimalkan durasi kunci.

4
RobPaller

Saya memiliki pengecualian khusus yang saya rasa harus disebutkan.

Dengan SQL Server 2012 Enterprise dan yang lebih baru, menambahkan kolom NOT NULL baru dengan konstanta runtime adalah operasi online yang diselesaikan secara instan dan tidak bergantung pada jumlah baris dalam tabel.

Informasi lebih lanjut tentang ini ditemukan di MSDN

Saya akan mereproduksi bagian penting

Dimulai dengan SQL Server 2012 (11.x) Edisi Perusahaan, menambahkan kolom NOT NULL dengan nilai default adalah operasi online ketika nilai default adalah konstanta runtime. Ini berarti bahwa operasi selesai hampir secara instan meskipun jumlah baris dalam tabel. Karena, baris yang ada di tabel tidak diperbarui selama operasi. Sebagai gantinya, nilai default disimpan hanya dalam metadata tabel dan nilainya dicari, sesuai kebutuhan, dalam kueri yang mengakses baris ini.

1
rince