Meningkatkan kecepatan hapus untuk SQL Server

12

Kami memiliki basis data produksi yang sangat besar, ukurannya sekitar 300GB. Apakah ada pendekatan untuk meningkatkan kinerja permintaan penghapusan? Saat ini kecepatan penghapusan antara 1-10k per menit, ini sangat lambat bagi kami.

Komunitas
sumber
2
1000 baris per menit terdengar sangat lambat. Apakah Anda mengalami pemblokiran? Atau apakah lambat untuk memilih baris juga, yang akan menyarankan perlunya indeks?
James Z
Mungkin Anda harus membuat indeks untuk mencakup kriteria penghapusan Anda.
Ginden
6
Tidak ada detail yang cukup untuk memberikan jawaban. Query mana yang Anda jalankan? Apakah Anda memiliki indeks pada kolom kriteria yang terlibat (jika ada)? Apakah Anda memiliki pemicu pada penghapusan? ...
Sébastien Sevrin
3
Apakah Anda mencoba menghapus satu miliar baris sekaligus? Apakah mungkin Anda menunggu autogrow setelah autogrow setelah autogrow? (Kemungkinan besar itu adalah aktivitas log yang Anda tunggu, bukan aktivitas hapus yang sebenarnya.) Lihat artikel ini ...
Aaron Bertrand
3
Juga. Adakah batasan kunci asing? Harap berikan definisi tabel lengkap, kueri, dan rencana eksekusi.
Martin Smith

Jawaban:

20

Jika Anda mencoba untuk menghapus sejumlah besar baris dalam satu pernyataan, maka kemungkinan Anda sedang menunggu aktivitas log. Jadi kamu bisa:

  1. Pastikan ukuran log Anda memadai sehingga peristiwa pertumbuhan tidak memperlambat Anda. Dengan pengaturan default, log Anda mungkin mulai dari 1MB dengan pertumbuhan 10%. Peristiwa pertumbuhan mahal, dan jika Anda mencatat bahkan 10 GB penghapusan, ini akan menghancurkan kinerja tidak hanya sekarang tetapi juga di masa depan (karena apa yang terjadi pada VLF).
  2. Jika Anda menghapus seluruh tabel, gunakan TRUNCATEatau DROP/ CREATE.
  3. Jika Anda menghapus sebagian besar tabel, gunakan SELECT INTOuntuk meletakkan data yang ingin Anda simpan ke tabel lain, lalu TRUNCATE, pindahkan porsi kecil kembali. (Atau cukup jatuhkan tabel lama, ganti nama baru, dan gunakan kembali batasan / izin dll.)
  4. Minimalkan dampak logging di tempat pertama dengan menghapus data dalam potongan bukan sekaligus. Lihat artikel ini . Anda juga dapat mempertimbangkan untuk beralih ke pemulihan sederhana sementara, sehingga Anda hanya perlu CHECKPOINTmenghapus log alih-alih mengambil cadangan log, tetapi Anda harus memastikan untuk mengembalikannya dan mengambil cadangan lengkap baru untuk memulai kembali rantai log .
Aaron Bertrand
sumber
+1, dari saya untuk artikel yang luar biasa. Ini telah membantu saya di masa lalu untuk membuat pengembang kami memahami operasi penghapusan ketika mereka terus menjangkau kami karena kelambatan dan pertumbuhan file log.
KASQLDBA
Juga, jika ada indeks yang tidak perlu, menjatuhkannya akan meningkatkan kecepatan penghapusan. Sekali lagi jika menghapus semua atau hampir semua data, menjatuhkan semua indeks terlebih dahulu dan membuatnya lagi setelahnya mungkin memiliki dampak yang bagus.
Tony Hinkle
3
@Tony menjatuhkan indeks juga harus dicatat (seperti halnya membuatnya), jadi mungkin hanya masalah kapan Anda ingin membayar biaya itu. Tanpa pengujian, saya tidak yakin ada keuntungan besar untuk skenario penghapusan (seperti akan ada untuk memasukkan / memperbarui), kecuali Anda memiliki indeks yang tidak akan Anda pertahankan sesudahnya.
Aaron Bertrand
Apakah penonaktifan sementara batasan FK dapat meningkatkan kueri?
Lev Z
3

Ada beberapa petunjuk, tetapi versi mana yang Anda gunakan? Apakah ini edisi perusahaan? Bagaimanapun:

  1. Jika Anda bisa, pindahkan log transaksi ke disk yang lebih cepat
  2. Analisis di mana . Apakah akan menggunakan indeks untuk mengidentifikasi catatan yang akan dihapus? Jika tidak, dapatkah Anda menambahkan indeks?
  3. Apakah Anda memiliki indeks di atas meja yang bisa Anda jatuhkan? Jika ya, jatuhkan.
  4. Apakah Anda memiliki kunci asing versus tabel ini? Ini benar-benar dapat memperlambat penghapusan Anda.
  5. Jika Anda memiliki edisi perusahaan dan bottleneck adalah disk IO, kompresi di tingkat baris, dapat memberi Anda sedikit bantuan (atau tidak, tergantung dari data Anda)
  6. Bisakah Anda mempartisi tabel? Indeks lokal dan drop partisi dapat lebih cepat.
  7. Selidiki di mana kemacetan melalui monitor aktivitas.

Tambahkan detail, ketika Anda bekerja dengan database besar tidak ada jawaban yang valid.

pengguna_0
sumber
0

Anda harus mencoba menghapusnya sepotong demi sepotong, mungkin menghapus dalam lingkaran, masing-masing menghapus iterasi itu transaksi sendiri dan kemudian menghapus log pada akhir setiap iterasi loop.

Selain itu, Anda perlu menemukan nomor yang akan Anda gunakan sebagai nilai dalam chunk untuk menghapus catatan. Perlu pengujian menyeluruh, akan lebih baik jika Anda bisa menguji nilai chunk di UAT terlebih dahulu.

Pada cara melanjutkan, akan merujuk Anda ke Hancurkan operasi penghapusan besar menjadi potongan-potongan

KASQLDBA
sumber
0

hapus bisa lambat jika tabel besar memiliki kunci asing rekursif.

jika demikian, temukan waktu yang tepat, nonaktifkan layanan dependend, nonaktifkan kunci asing rekursif, lakukan penghapusan besar-besaran, lalu pulihkan kunci asing lagi.

obratim
sumber
ini persis kasus saya. Agak berisiko untuk menonaktifkan contraint, tetapi penghapusan berubah dari 1 baris / seocnd ke 500 / detik
Jurion
0

Menambahkan beberapa poin lagi ...

  1. Coba periksa apakah predikat memiliki indeks dan lihat juga statistik.
  2. Jika Anda menghapus banyak baris dan Anda juga tidak ingin opsi temp table. Pilih tablockopsi.
  3. Lihat apakah Anda memiliki pemicu, khususnya setelah menghapus pemicu.

Untuk mendapatkan bantuan lebih lanjut, kirim pertanyaan yang Anda gunakan, info tabel plus info pemblokiran.

TheGameiswar
sumber