Saya telah melakukan ini pada indeks tertentu sebelum sekarang, untuk membantu permintaan yang sering kali dijalankan. Secara efektif apa yang telah mereka lakukan adalah membuat beberapa indeks berkerumun: ketika salah satu dari indeks tersebut digunakan untuk menemukan baris, tidak diperlukan pekerjaan tambahan untuk mencari sisa data dalam indeks berkerumun nyata (atau tumpukan jika tidak ada indeks berkerumun nyata) .
apakah ini strategi yang masuk akal?
Untuk beberapa indeks di mana diperlukan untuk mendukung pola permintaan tertentu, tentu saja ya.
Tetapi untuk melakukan ini dengan semua indeks, saya hanya akan mengatakan tidak.
Ini akan membuang-buang ruang untuk melakukan di tempat yang tidak benar-benar dibutuhkan, dan akan memperlambat sisipan / pembaruan secara signifikan. Ini mungkin memperlambat permintaan baca sebanyak yang membantu juga, karena setiap halaman indeks menyimpan lebih sedikit catatan sehingga permintaan apa pun yang perlu merujuk potongan indeks untuk difilter tetapi tidak menggunakan semua kolom lain harus mengakses lebih banyak halaman. Ini akan membuat database Anda lebih haus-memori: halaman-halaman tersebut perlu dimuat ke dalam buffer pool, berpotensi mengeluarkan halaman-halaman lain yang bermanfaat jika memori rendah. Jika kompresi digunakan pada indeks tersebut untuk mencoba mengurangi efek pada persyaratan penyimpanan dan memori, maka itu akan mendorong beban tambahan ke CPU sebagai gantinya.
karena akses adalah melalui ORM yang secara default (tetapi tidak selalu) mengambil semua kolom
Ini adalah pola umum dengan penggunaan ORM yang kurang optimal (atau hanya ORM naif) dan dalam kasus ini saya telah melihat penasihat indeks SQL Server (dan alat pihak ketiga yang serupa) menyarankan indeks dengan banyak INCLUDE
kolom d, jadi saya akan setuju dengan Anda saran bahwa inilah mengapa indeks telah dibuat dengan cara ini.
Tapi sementara itu mungkin membuat semua pertanyaan seperti itu sedikit lebih cepat dan beberapa dari mereka secara signifikan lebih cepat, saya menduga bahwa dalam banyak kasus, manfaatnya sangat kecil sehingga tidak sebanding dengan jejak memori tambahan yang dibutuhkan oleh set kerja umum Anda, ruang pada disk, dan IO antara disk dan memori.
Juga ingat bahwa ORM mungkin tidak memilih semua kolom dari semua tabel yang disentuh oleh kueri, sehingga manfaat mungkin hanya berlaku untuk target utama permintaan saat ini, dan indeks yang lebih besar dapat menghukum kueri saat objek lain digunakan untuk memfilter tetapi tidak mengembalikan data ( SELECT * FROM table1 WHERE id IN (SELECT someID FROM table2 WHERE someColumn='DesiredValue')
mungkin).
Pertimbangan lain untuk kelebihan ruang yang digunakan, terutama jika datanya besar, adalah bahwa hal itu akan berdampak pada strategi cadangan Anda: biaya penyimpanan dan transfer untuk cadangan tersebut, waktu pemulihan potensial, dan sebagainya.
haruskah kita bersiap untuk perbedaan antara keduanya [on-prem & AzureSQL]
Secara umum saya pikir pertimbangan di sini akan sama dalam setiap kasus, meskipun setiap kelebihan memori / biaya IO yang dikenakan oleh indeks besar mungkin lebih langsung terlihat di Azure di mana Anda dapat mengubah tingkat layanan dan karenanya biaya infrastruktur lebih mudah daripada memiliki sumber daya perangkat keras yang relatif tetap. Jika menggunakan tingkatan standar / premium alih-alih penetapan harga berbasis vcore maka Anda akan lebih terpengaruh oleh biaya IO dalam standar karena premium mencakup lebih banyak IO per DTU secara signifikan. Jika Anda menggunakan cadangan multi-wilayah atau redundansi atau fitur non-lokal lainnya di Azure daripada mungkin ada biaya bandwidth yang terkait dengan ruang ekstra yang diambil oleh indeks lebar yang tidak sempurna.
SELECT
tanpa menentukanORDER BY
mulai mengembalikan baris yang sama seperti sebelumnya tetapi dengan urutan sewenang-wenang yang berbeda.Dalam kebanyakan kasus ini bukan strategi yang masuk akal. Alasannya, bahwa dalam database OLTP umum, baris yang dikembalikan ke pengguna akhir tidak akan banyak. (Generalisasi)
Pertanyaan yang harus Anda tanyakan pada diri sendiri adalah, jika Anda mencari di kolom kunci, berapa banyak baris yang akan dikembalikan oleh operasi pencarian itu? Dan ulangi untuk kueri yang mencari di kolom itu.
Pertimbangkan tabel berikut, kembalikan banyak kolom,
where SelectiveIDField= ...
Jika hanya satu baris yang akan dikembalikan oleh pencarian
selectiveIDField
, apakah pencarian kunci tambahan adalah hal yang buruk? (menduga Anda memiliki indeks berkerumun di sini, jika tidak, cari RID)Itu hanya akan melakukan satu pencarian kunci tambahan, satu eksekusi tambahan + operator bergabung. Bahkan jika itu 10 atau bahkan 100, apakah dampaknya akan sebesar itu? Ini juga tergantung pada seberapa banyak permintaan Anda dieksekusi dan seberapa penting waktu eksekusi.
Dalam hal itu diabaikan, cukup buat indeks
SelectiveIDField
dan sebut sehari, itu tidak sepadan dengan keuntungan baca dibandingkan dengan kerugian menulis.Jadi singkatnya, membuat indeks pada seluruh tabel seharusnya menurut saya bukan pendekatan default kecuali Anda benar-benar melihat masalah dengan kueri dan dapat memperbaikinya secara drastis dengan menambahkan seluruh indeks penutup.
sumber