Proyek kami menjalankan basis data yang sangat besar, sangat rumit. Jadi sekitar sebulan yang lalu, kami perhatikan bahwa ruang yang digunakan oleh kolom yang diindeks berisi nilai nol menjadi terlalu besar. Sebagai tanggapan terhadap hal itu, saya menulis sebagai skrip yang secara dinamis akan mencari semua indeks satu kolom yang berisi lebih dari 1% dari nilai nol, lalu jatuhkan dan buat kembali indeks tersebut sebagai indeks yang difilter dengan syarat bahwa nilainya TIDAK NULL. Ini akan menjatuhkan dan menciptakan kembali ratusan indeks di seluruh database dan biasanya membebaskan hampir 15% dari ruang yang digunakan oleh seluruh DB.
Sekarang saya punya dua pertanyaan tentang ini:
A) Apa kerugian menggunakan indeks yang difilter dengan cara ini? Saya akan berasumsi bahwa itu hanya akan meningkatkan kinerja, tetapi apakah ada risiko kinerja yang terlibat?
B) Kami menerima kesalahan ( 'tidak dapat menjatuhkan indeks XYZ karena tidak ada atau Anda tidak memiliki izin' ) saat menjatuhkan dan membuat ulang indeks, meskipun saat diperiksa setelahnya, semuanya berjalan persis seperti yang diharapkan. Bagaimana ini bisa terjadi?
Terima kasih atas bantuannya!
Sunting: Menanggapi @Thomas Kejser
Hai dan terima kasih, tetapi ternyata ini adalah bencana. Saat itu kami tidak mengerti beberapa hal seperti:
- Selama kueri, SQLOS membuat rencana indeks sebelum menentukan bahwa ia tidak dapat menggunakan nilai NULL untuk bergabung dengan kolom tabel. Yaitu, Anda benar-benar perlu memiliki filter klausa WHERE yang sesuai dengan indeks untuk setiap indeks yang difilter yang digunakan dalam kueri, atau indeks tidak akan digunakan sama sekali.
- Menjatuhkan dan membuat indeks dan memperbarui statistik mereka secara berlebihan lagi setelah itu mungkin masih belum cukup untuk menghasilkan rencana yang diperbarui, yang kami asumsikan akan melakukannya. Tampaknya dalam beberapa kasus hanya beban kerja yang cukup tinggi akan memaksa SQL Server untuk menilai kembali rencana.
- Ada beberapa eksotik untuk fungsionalitas perencana eksekusi yang sulit ditentukan oleh akal sehat dan logika saja. Dengan ribuan variasi kode-belakang-yang dihasilkan dari permintaan yang berbeda bahkan, indeks yang tampaknya tidak berguna dapat membantu dalam beberapa statistik dan rencana permintaan yang akhirnya digunakan dalam permintaan kritis.
Pada akhirnya, perubahan ini dikembalikan. Jadi indeks yang difilter adalah alat yang ampuh, tetapi Anda harus benar-benar memahami dengan tepat data apa yang diambil dari kolom tersebut. Di mana indeks normal selain dari masalah ruang agak mudah diterapkan, indeks yang difilter mewakili solusi yang sangat khusus. Mereka tentu bukan pengganti untuk indeks reguler, melainkan perpanjangan untuk mereka dalam keadaan khusus yang mereka butuhkan.
Jawaban:
Pendekatan yang sangat menarik. Suara positif saya untuk kreativitas.
Karena Anda mendapatkan kembali ruang tersebut, saya menganggap indeks asli sudah tidak ada lagi? Kelemahan dari indeks yang difilter adalah:
Secara praktis, ini berarti Anda harus sangat berhati-hati dengan indeks yang difilter karena akan sering menghasilkan rencana kueri yang mengerikan. Saya tidak akan sampai menyebut mereka tidak berguna, tetapi saya melihatnya sebagai tambahan pada indeks tradisional, bukan sebagai pengganti (seperti yang Anda coba lakukan).
sumber
Thomas Kejser menjawab topik ini di atas.
Saya hanya berpikir tentang menambahkan 2 sen.
Saya telah melihat beberapa indeks yang difilter hanya digunakan (diperlihatkan dalam rencana eksekusi) ketika Anda sama persis dengan klausa di mana dalam kueri Anda sebagai di mana dalam indeks yang difilter.
Sudahkah Anda mencoba menggunakan tampilan yang diindeks ? kolom jarang ?
Saya percaya bahwa sejauh Anda hanya memiliki sambungan dalam, Anda dapat membuat tampilan yang diindeks berisi klausa mana dari indeks yang difilter dan kemudian Anda dapat menggunakan tampilan tersebut.
Mungkin ada lebih dari satu tampilan. Tetapi sama dengan indeks yang tidak berkerumun, terlalu banyak akan memperlambat penulisan Anda.
Dalam pengalaman saya, Anda akan memiliki keuntungan yang baik dalam membaca tetapi Anda harus memantau menulis (sisipan dan pembaruan) khususnya jika tabel terlibat dalam replikasi.
Namun, karena saya mengerti perhatian utama Anda
the null values
karena itu saya akan menyarankan Anda kolom SPARSE dalam indeks Anda .Kolom jarang sangat cocok untuk indeks yang difilter
Karena saya telah mengiklankan kolom jarang, saya tidak akan merasa baik jika saya tidak memberi tahu Anda tentang batasannya juga:
Sebagai akibatnya
Perhatikan contoh tabel yang memiliki 600 kolom tipe bigint yang jarang.
lebih detail tentang tautan di atas, namun saya lebih suka memposting di sini peringatan ini juga:
Mesin Database SQL Server menggunakan prosedur berikut untuk melakukan perubahan ini:
1 - Menambahkan kolom baru ke tabel dalam ukuran dan format penyimpanan baru.
2 - Untuk setiap baris dalam tabel, perbarui dan salin nilai yang disimpan di kolom lama ke kolom baru.
3 - Menghapus kolom lama dari skema tabel.
4 - Membangun kembali tabel (jika tidak ada indeks berkerumun) atau membangun kembali indeks berkerumun untuk merebut kembali ruang yang digunakan oleh kolom lama.
sumber