Mengapa Indeks Nonclustered Saya Menggunakan Lebih Banyak Ruang Ketika Saya Menghapus Baris?

22

Saya memiliki meja besar dengan 7,5 miliar baris dan 5 indeks. Ketika saya menghapus sekitar 10 juta baris, saya perhatikan bahwa indeks yang tidak tercakup tampaknya menambah jumlah halaman tempat mereka disimpan.

Saya menulis permintaan dm_db_partition_statsuntuk melaporkan perbedaan (setelah - sebelumnya) di halaman:

delta dm_db_partition_stats

Indeks 1 adalah indeks berkerumun, Indeks 2 adalah kunci utama. Yang lain tidak tertutup dan tidak unik.

Mengapa halaman meningkat pada indeks non-cluster itu?
Saya berharap angkanya paling buruk tetap sama.
Saya melihat penghitung kinerja melaporkan peningkatan pemisahan halaman selama penghapusan.

Saat menghapus, apakah catatan hantu harus pindah ke halaman lain? Apakah ini ada hubungannya dengan "penyunat unik"?

Kami berada di tengah meluncurkan RCSI, tetapi sekarang, RCSI tidak aktif.

Ini adalah simpul utama dalam grup ketersediaan. Saya tahu bahwa snapshot digunakan entah bagaimana pada secondaries. Saya akan terkejut jika itu relevan. Saya berencana untuk menggali ini (mencari output halaman dbcc) untuk mempelajari lebih lanjut. Inilah harapan seseorang telah melihat sesuatu yang serupa.

Michael J Swart
sumber
Hanya sebuah pertanyaan - menjalankan REORGANISASI di salah satu indeks yang tumbuh, apa yang terjadi? Berapa banyak halaman yang dihapus? Dan jika Anda Mengatur Ulang sebelum menghapus, apa yang terjadi? Saya sebagian besar berpikir bahwa mekanisme internal mungkin merasa lebih mudah dalam beberapa kasus untuk mengalokasikan seluruh halaman baru dan bergabung, tetapi tidak membersihkan halaman yang kosong. Saya tahu bahwa REORGANIZE pada akhirnya menjatuhkan jumlah halaman yang signifikan, bahkan pada indeks yang relatif tidak terfragmentasi tetapi lebih besar.
Laughing Vergil
Pertanyaan bagus @LaughingVergil Ketika saya punya jawabannya, saya akan kembali ke sini untuk melaporkannya. (Tapi mungkin butuh beberapa saat).
Michael J Swart
Dalam kasus kami, peningkatan ini adalah fenomena sementara. Dengan kesabaran yang cukup, pembersihan hantu akhirnya berhasil dan ukuran indeks menurun.
Michael J Swart

Jawaban:

28

Satu skenario yang mungkin sangat menghibur saya:

  • Baris awalnya ditulis ketika database tidak memiliki Baca Komitmen Snapshot (RCSI), Snapshot Isolasi (SI), atau Grup Ketersediaan (AG) diaktifkan
  • RCSI atau SI diaktifkan, atau database ditambahkan ke dalam Grup Ketersediaan
  • Selama penghapusan, cap waktu 14 byte ditambahkan ke baris yang dihapus untuk mendukung pembacaan RCSI / SI / AG

Karena server ini adalah yang utama di AG, itu terpengaruh seperti yang kedua. Info versi ditambahkan pada primer - halaman data sama persis pada primer dan sekunder. Sekunder memanfaatkan toko versi untuk melakukan pembacaan saat baris diperbarui oleh AG, tetapi sekunder tidak menulis versi mereka sendiri dari timestamp ke halaman. Mereka hanya mewarisi versi dari karya utama.

Untuk menunjukkan pertumbuhan, saya mengambil ekspor database Stack Overflow (yang tidak memiliki RCSI diaktifkan) dan membuat banyak indeks pada tabel Posting. Saya memeriksa ukuran indeks dengan sp_BlitzIndex @Mode = 2 (menyalin / menempel ke spreadsheet, dan membersihkan sedikit untuk memaksimalkan kepadatan info):

sp_BlitzIndex sebelumnya

Saya kemudian menghapus sekitar setengah dari baris:

BEGIN TRAN;
DELETE dbo.Posts WHERE Id % 2 = 0;
GO

Yang mengherankan, ketika penghapusan terjadi, file data tumbuh untuk mengakomodasi cap waktu juga! Laporan Penggunaan Disk SSMS menunjukkan peristiwa pertumbuhan - inilah hanya bagian atas yang diilustrasikan:

Peristiwa pertumbuhan

(Harus menyukai demo di mana penghapusan membuat basis data tumbuh.) Sementara penghapusan berjalan, saya menjalankan sp_BlitzIndex lagi Perhatikan bahwa indeks berkerumun memiliki lebih sedikit baris, tetapi ukurannya telah tumbuh sekitar 1,5GB. Indeks nonclustered pada AcceptedAnswerId telah tumbuh secara dramatis - mereka indeks pada nilai kecil yang sebagian besar nol, sehingga ukuran indeks mereka hampir dua kali lipat!

sp_BlitzIndex selama penghapusan

Saya tidak perlu menunggu penghapusan selesai untuk membuktikannya, jadi saya akan menghentikan demo di sana. Poinnya adalah: ketika Anda melakukan penghapusan besar pada tabel yang diimplementasikan sebelum RCSI, SI, atau AG diaktifkan, indeks (termasuk berkerumun) benar-benar dapat tumbuh untuk mengakomodasi penambahan stempel waktu versi toko.

Brent Ozar
sumber
3
Inilah penjelasannya. Ternyata ada keadaan lain yang dapat menyebabkan hilangnya 14 byte versi. Dalam pengujian saya tampaknya membangun kembali indeks offline akan membangun kembali baris tanpa versi byte.
Michael J Swart