Kapan boleh menyusutkan Database?

43

Saya tahu shrink adalah iblis: Ia membalik urutan halaman dan bertanggung jawab atas kanker kulit, fragmentasi data, dan pemanasan global. Daftarnya berlanjut ... Yang mengatakan, katakanlah saya memiliki database 100 GB dan saya menghapus 50 GB data - bukan pada satu tabel, tetapi pemangkasan umum data lama pada tingkat basis data yang luas, mencakup 90% dari tabel - apakah ini merupakan kasus penggunaan yang tepat untuk menyusutkan database?

Jika tidak, apa langkah yang tepat untuk dilakukan untuk membersihkan rumah setelah menghapus persentase data yang begitu tinggi dari basis data? Saya dapat memikirkan dua: Rebuild Indexes dan Update Stats. Apa lagi?

bumble_bee_tuna
sumber

Jawaban:

13

Reorganisasi dan menyusut tidak pernah disarankan.

Jika Anda dapat mengambil aplikasi yang dilayani database secara offline, Anda dapat mempercepat proses dan mengurangi fragmentasi indeks dengan menghapus semua indeks dan batasan kunci asing / kunci sebelum menyusut (ini akan berarti ada lebih sedikit data untuk dipindahkan karena hanya halaman data akan diacak bukan halaman indeks yang sekarang tidak ada, mempercepat proses) kemudian menciptakan kembali semua indeks dan kunci.

Menciptakan indeks setelah menyusut berarti tidak boleh terfragmentasi secara signifikan, dan setelah hilang selama menyusut berarti membangun kembali tidak akan meninggalkan banyak "lubang" kecil di alokasi halaman dalam file yang dapat mengundang fragmentasi nanti.

Opsi lain jika Anda dapat offline aplikasi adalah untuk memigrasi semua data ke database baru dari struktur yang sama. Jika proses build Anda solid, Anda seharusnya dapat membangun DB kosong itu dengan cepat, jika tidak membuatnya dari DB saat ini (mengembalikan cadangan yang sekarang, pangkas / hapus semua konten dalam tabel dan lakukan penyusutan penuh).

Anda mungkin masih ingin menghapus semua indeks di tujuan dan membuatnya kembali setelah itu karena ini bisa jauh lebih efisien ketika mengubah banyak data yang diindeks (100% dari itu dalam kasus ini). Untuk mempercepat proses penyalinan, minta file data dari database tujuan pada drive fisik yang berbeda ke sumbernya (kecuali jika Anda menggunakan SSD dalam hal ini Anda tidak perlu peduli untuk mengurangi pergerakan head), Anda dapat memindahkannya ke lokasi sumber ketika Anda selesai.

Juga, jika membuat tujuan sebagai baru (daripada dengan mengosongkan salinan sumber) buat dengan ukuran awal yang akan berisi semua data saat ini ditambah beberapa bulan pertumbuhan - yang akan membuat salinan data sedikit lebih cepat lagi sebagai itu tidak akan mengalokasikan ruang baru setiap saat selama proses.

Ini mungkin lebih baik daripada menggunakan shrink karena memigrasikan data ke database baru mereplikasi tindakan yang dimaksudkan dari operasi shrink, tetapi berpotensi dengan fragmentasi yang jauh lebih sedikit (yang merupakan konsekuensi yang tidak diinginkan dari reorganisasi dan penyusutan). Seorang psikiater hanya mengambil blok dari dekat akhir file dan menempatkan mereka di ruang pertama di dekat awal tidak berusaha untuk menjaga data terkait bersama.

Saya menduga hasilnya akan lebih hemat ruang-bijaksana juga karena ada kemungkinan akan lebih sedikit halaman yang digunakan setelahnya. Penyusutan hanya akan memindahkan halaman yang digunakan sebagian, memindahkan data lebih cenderung menghasilkan halaman penuh terutama jika Anda memasukkan ke tujuan dalam urutan kunci / indeks berkerumun tabel (di mana tabel memiliki satu) dan membuat indeks lainnya setelah semua data dimigrasikan.

Tentu saja jika Anda tidak dapat membuat aplikasi offline sama sekali, hanya menjalankan psikiater adalah satu-satunya pilihan Anda jadi jika Anda benar - benar perlu merebut kembali ruang dengan itu. Tergantung pada data Anda, pola akses, ukuran set kerja yang umum, berapa banyak RAM yang dimiliki server, dan sebagainya, fragmentasi internal tambahan mungkin tidak terlalu signifikan pada akhirnya.

Untuk operasi penyalinan, baik SSIS atau basis T-SQL akan bekerja dengan baik (opsi SSIS mungkin kurang efisien, tetapi berpotensi lebih mudah untuk dipertahankan nanti). Jika Anda membuat hubungan FK di bagian akhir bersama dengan indeks Anda dapat melakukan sederhana "untuk setiap tabel, salin" dalam kedua kasus. Tentu saja untuk sekali saja, psikiater + reorganisasi mungkin juga baik, tetapi saya hanya ingin menakut-nakuti orang agar tidak pernah mempertimbangkan psikiater biasa! (Saya sudah tahu orang menjadwalkannya setiap hari).

David Spillett
sumber
16

Apakah basis data akan tumbuh lagi? Jika demikian maka upaya Anda akan dimasukkan ke dalam operasi menyusut hanya akan menjadi sia-sia, karena ketika Anda memiliki ukuran file turun dan kemudian Anda menambahkan lebih banyak data, file hanya akan tumbuh lagi, dan transaksi harus menunggu pertumbuhan itu terjadi. Jika Anda memiliki pengaturan pertumbuhan otomatis yang kurang optimal dan / atau drive lambat, aktivitas pertumbuhan ini akan sangat menyakitkan.

Jika Anda mengecilkan basis data, untuk apa Anda menggunakan ruang disk yang dibebaskan? Sekali lagi jika Anda hanya ingin menjaga ruang itu kosong jika database ini tumbuh lagi, maka Anda hanya memutar roda Anda.

Apa yang mungkin Anda pertimbangkan lakukan, sekarang setelah Anda memiliki semua ruang kosong di file ini, adalah membangun kembali indeks Anda sehingga mereka lebih optimal (dan akan jauh lebih tidak menyakitkan untuk melakukan ini ketika Anda memiliki ruang kosong untuk melakukannya - Pikirkan tentang mencoba mengganti sweter di lemari kecil vs kamar tidur besar).

Jadi, kecuali ini adalah operasi pembersihan besar dan Anda benar-benar tidak akan naik ke tingkat data yang sama lagi, saya hanya akan membiarkannya apa adanya dan fokus pada bidang optimasi lainnya.

Aaron Bertrand
sumber
@Arron Bertrand Yah butuh 10 tahun untuk mendapatkan yang besar dan disk agak menjadi perhatian karena saya ingin meletakkannya dalam keadaan padat. Saya berpikir untuk menyusut ke 60GB dengan pertumbuhan 5GB. Sungguh satu-satunya hal yang Anda rekomendasikan adalah membangun kembali indeks, ya? Saya pikir orang akan memiliki beberapa rekomendasi lagi.
bumble_bee_tuna
Dan saya hanya akan merekomendasikan pembangunan kembali jika mereka membutuhkannya. Tapi saya akan melakukannya sebelum Anda mengecilkan file. Tidak dapat benar-benar memikirkan apa pun di luar kepala saya yang akan Anda lakukan dengan ruang kosong yang akan memberikan optimalisasi kinerja dalam kasus umum ...
Aaron Bertrand
2

Jika Anda kehabisan ruang, dan data Anda tidak seharusnya sebesar itu maka menyusut, tetapi membangun kembali indeks Anda setelah dengan faktor pengisian yang sesuai yang memungkinkan untuk pertumbuhan khas.

Jika tujuan akhir Anda sebenarnya adalah untuk mengurangi ukuran cadangan, pastikan Anda menerapkan strategi cadangan komprehensif untuk menghapus log transaksi dan ketika Anda mencadangkan db, gunakan opsi kompres.

Saya tidak akan merekomendasikan pertumbuhan otomatis 5GB kecuali Anda biasanya akan mengharapkan untuk tumbuh 5GB sering. Anda bisa mengalami masalah kinerja yang terputus-putus. Ukuran data Anda pertama-tama harus ditetapkan sesuai dengan apa yang menurut Anda diperlukan untuk, katakanlah, satu tahun, dan Pertumbuhan Otomatis harus diatur ke ukuran yang Anda uji tidak mempengaruhi kinerja operasi. Lihat Jangan Sentuh Tombol Kecilkan Basis Data di SQL Server! oleh Mike Walsh.

Membangun kembali indeks sebelum menyusut menyebabkan indeks menjadi sangat buruk. Tidak baik untuk membangun kembali lalu menyusut. Penyusutan menyebabkan indeks menjadi hancur untuk memulihkan ruang - jadi membangun kembali sebelumnya lalu menyusut tidak ada gunanya. Lihat Kapan menggunakan Shrink Otomatis oleh Thomas LaRock.

GilesDMiddleton
sumber
Jika Anda mengecilkan lalu membangun kembali indeks, file data hanya akan harus tumbuh lagi untuk mengakomodasi salinan data yang digunakan untuk membangun kembali. Meskipun tidak akan sebesar file data asli dalam kasus ini, itu masih akan tumbuh dan tampaknya tidak produktif. Membangun kembali sementara ada ruang kosong akan lebih cepat (tidak diperlukan pertumbuhan otomatis) dan umumnya masih akan lebih baik daripada yang Anda sarankan tentang cara meletakkan halaman untuk salinan indeks baru, dan saya menduga dalam banyak kasus ini secara keseluruhan ini akan secara keseluruhan lebih pendek dan menyebabkan pemulihan ruang disk yang sama atau lebih baik. Mungkin saatnya untuk beberapa tes.
Aaron Bertrand
Dan tentu saja ini dengan asumsi indeks pada data yang tersisa benar-benar perlu dibangun kembali - mungkin sudah dalam kondisi yang cukup baik.
Aaron Bertrand
1

Saya tidak tahu apakah ini akan bekerja lebih baik daripada pengindeksan ulang setelah menyusut tetapi pilihan lain adalah membuat file data baru yang berukuran tepat dan memindahkan semua data ke sana. Dalam hal ini saya akan melakukan pengindeksan ulang terlebih dahulu sehingga Anda tahu apa ukuran data yang sebenarnya. Satu tangkapan adalah bahwa jika ini adalah file pertama dalam file data primer saya tidak berpikir Anda bisa mengosongkannya. Anda harus dapat mengecilkannya kemudian memindahkan data kembali sesudahnya dan itu akan menghindari pembalikan halaman. Namun, jika Anda ingin pindah ke kondisi solid yang seharusnya tidak membuat perbedaan besar.

cfradenburg
sumber
1

Kembali ke WAY ini terlambat. Namun, kami telah merenungkan dan menguji penggunaan shrink di lingkungan pengujian kami untuk waktu yang lama juga. Sebagai per topik, ada yang kalanya psikiater adalah pilihan yang layak. Tetapi mengetahui kapan dan bagaimana menerapkannya, sangat penting untuk eksekusi yang tepat baik dalam jangka panjang dan pendek.

Dalam skenario kami, kami baru-baru ini menambahkan banyak perubahan pada DB besar kami termasuk kompresi, partisi, pengarsipan, dan penghapusan data berlebihan yang lama. Akibatnya, bagian yang digunakan dari file data utama kami turun menjadi kurang dari setengahnya. Tapi apa gunanya membawa semua barang bawaan itu? Terutama karena bertentangan dengan beberapa artikel di web, ukuran file data Anda SECARA LANGSUNG TERKAIT DENGAN CADANGAN / KEMBALIKAN DURASI. Itu karena tidak seperti banyak artikel yang berasumsi, skenario kehidupan nyata memiliki lebih banyak data pada halaman tertentu daripada hanya hal-hal yang mungkin Anda hapus.

Lebih penting lagi, ini membuka skenario hebat untuk menyusut:

  1. Buat skrip yang akan menemukan semua objek dan grup-grup mereka di database Anda (banyak contoh online), gunakan ini untuk membuat klausa drop serta membuat definisi untuk setiap indeks dan kendala Anda.
  2. Buat file & filegroup baru, dan jadikan default.
  3. Jatuhkan semua indeks yang tidak tercakup (perhatikan, beberapa indeks bisa menjadi kendala).
  4. Buat indeks berkerumun Anda pada filegroup baru dengan DROP_EXISTING = ON (yang, btw, adalah operasi yang sangat cepat, minimal dicatat untuk memulai dibandingkan dengan banyak alternatif).
  5. Buat kembali indeks yang tidak tercakup.
  6. Terakhir, SHRINK file data lama Anda (biasanya PRIMARY).

Dengan cara ini, satu-satunya data yang tersisa di sana akan menjadi objek sistem DB Anda, statistik, prosedur dan yang lainnya. Susut harus jauh, JAUH lebih cepat, dan tidak perlu untuk pemeliharaan indeks lebih lanjut pada objek data utama Anda yang akan dibuat dengan rapi agar dan risiko minimal untuk fragmentasi di masa depan.

Kahn
sumber