Saat belajar untuk ujian 70-433 saya perhatikan Anda dapat membuat indeks penutup dalam salah satu dari dua cara berikut.
CREATE INDEX idx1 ON MyTable (Col1, Col2, Col3)
-- ATAU --
CREATE INDEX idx1 ON MyTable (Col1) INCLUDE (Col2, Col3)
Klausa INCLUDE baru bagi saya. Mengapa Anda menggunakannya dan pedoman apa yang akan Anda sarankan dalam menentukan apakah akan membuat indeks penutup dengan atau tanpa klausa TERMASUK?
SELECT
dan untuk sebagian tidak? \Anda akan menggunakan INCLUDE untuk menambahkan satu atau lebih kolom ke tingkat daun dari indeks yang tidak berkerumun, jika dengan melakukannya, Anda dapat "menutupi" kueri Anda.
Bayangkan Anda perlu menanyakan ID karyawan, ID departemen, dan nama belakang.
Jika Anda memiliki indeks non-clustered pada (EmployeeID, DepartmentID), setelah Anda menemukan karyawan untuk departemen yang diberikan, Anda sekarang harus melakukan "pencarian bookmark" untuk mendapatkan catatan penuh karyawan yang sebenarnya, hanya untuk mendapatkan kolom nama belakang . Itu bisa menjadi sangat mahal dalam hal kinerja, jika Anda menemukan banyak karyawan.
Jika Anda memasukkan nama belakang itu dalam indeks Anda:
maka semua informasi yang Anda butuhkan tersedia di tingkat daun dari indeks non-clustered. Hanya dengan mencari di indeks non-cluster dan menemukan karyawan Anda untuk departemen tertentu, Anda memiliki semua informasi yang diperlukan, dan pencarian bookmark untuk setiap karyawan yang ditemukan dalam indeks tidak lagi diperlukan -> Anda menghemat banyak waktu.
Jelas, Anda tidak dapat memasukkan setiap kolom dalam setiap indeks yang tidak berkerumun - tetapi jika Anda memang memiliki kueri yang hanya kehilangan satu atau dua kolom untuk "dicakup" (dan yang sering digunakan), akan sangat membantu TERMASUK bagi mereka menjadi indeks non-cluster yang cocok.
sumber
JOIN
kunci dalam kueri, danINCLUDE
s perlu data yang Anda ambil tetapi tidak diurutkan.Diskusi ini kehilangan poin penting: Pertanyaannya bukan apakah "kolom-bukan-kunci" lebih baik dimasukkan sebagai indeks- kolom atau sebagai -kolom yang disertakan .
Pertanyaannya adalah seberapa mahal menggunakan mekanisme sertakan untuk memasukkan kolom yang tidak benar-benar diperlukan dalam indeks ? (biasanya bukan bagian dari mana-klausa, tetapi sering termasuk dalam pemilihan). Jadi dilema Anda selalu:
Di mana: id1, id2 ... idN adalah kolom yang sering digunakan dalam pembatasan dan col1, col2 ... colN adalah kolom yang sering dipilih, tetapi biasanya tidak digunakan dalam pembatasan
(Pilihan untuk memasukkan semua kolom ini sebagai bagian dari kunci-indeks selalu konyol (kecuali jika mereka juga digunakan dalam pembatasan) - karena akan selalu lebih mahal untuk mempertahankannya karena indeks harus diperbarui dan disortir bahkan ketika "kunci" tidak berubah).
Jadi gunakan opsi 1 atau 2?
Jawaban: Jika tabel Anda jarang diperbarui - sebagian besar dimasukkan ke / dihapus dari - maka relatif murah untuk menggunakan mekanisme-sertakan untuk memasukkan beberapa "kolom panas" (yang sering digunakan dalam pemilihan - tetapi tidak sering digunakan pada pembatasan) karena sisipan / penghapusan memerlukan indeks untuk diperbarui / disortir dan dengan demikian sedikit overhead tambahan terkait dengan menyimpan beberapa kolom tambahan saat sudah memperbarui indeks. Overhead adalah memori tambahan dan CPU yang digunakan untuk menyimpan info yang berlebihan pada indeks.
Jika kolom yang Anda pertimbangkan untuk ditambahkan sebagai kolom disertakan sering diperbarui (tanpa kunci indeks - kolom diperbarui) - atau - jika begitu banyak sehingga indeks menjadi dekat dengan salinan tabel Anda - gunakan opsi 1 Saya sarankan! Juga jika menambahkan kolom-sertakan tertentu ternyata tidak membuat perbedaan kinerja - Anda mungkin ingin melompati gagasan untuk menambahkannya :) Verifikasi bahwa mereka berguna!
Jumlah rata-rata baris per nilai yang sama dalam kunci (id1, id2 ... idN) dapat menjadi sangat penting.
Perhatikan bahwa jika kolom - yang ditambahkan sebagai kolom-indeks yang disertakan - digunakan dalam batasan : Selama indeks dapat digunakan (berdasarkan pembatasan terhadap indeks- kunci- kolom) - maka SQL Server cocok pembatasan kolom terhadap indeks (leaf-node-values) alih-alih menggunakan cara yang mahal di sekitar tabel itu sendiri.
sumber
Kolom indeks dasar diurutkan, tetapi kolom yang disertakan tidak diurutkan. Ini menghemat sumber daya dalam mempertahankan indeks, sambil tetap memungkinkan untuk memberikan data di kolom yang disertakan untuk mencakup permintaan. Jadi, jika Anda ingin mencakup kueri, Anda dapat menempatkan kriteria pencarian untuk menemukan baris ke kolom yang diurutkan dari indeks, tetapi kemudian "memasukkan" kolom tambahan yang tidak disortir dengan data non-pencarian. Ini pasti membantu mengurangi jumlah penyortiran dan fragmentasi dalam pemeliharaan indeks.
sumber
Alasan mengapa (termasuk data di tingkat daun indeks) telah dijelaskan dengan baik. Alasan Anda memberikan dua getar tentang ini, adalah bahwa ketika Anda menjalankan kueri Anda, jika Anda tidak memiliki kolom tambahan termasuk (fitur baru di SQL 2005) SQL Server harus pergi ke indeks berkerumun untuk mendapatkan kolom tambahan yang membutuhkan lebih banyak waktu, dan menambahkan lebih banyak memuat ke layanan SQL Server, disk, dan memori (buffer cache untuk lebih spesifik) karena halaman data baru dimuat ke dalam memori, berpotensi mendorong data lain yang lebih sering dibutuhkan keluar dari cache buffer.
sumber
Pertimbangan tambahan yang belum saya lihat dalam jawaban yang sudah diberikan, adalah kolom yang disertakan dapat berupa tipe data yang tidak diizinkan sebagai kolom kunci indeks, seperti varchar (maks).
Ini memungkinkan Anda untuk memasukkan kolom seperti itu dalam indeks penutup. Saya baru-baru ini harus melakukan ini untuk memberikan permintaan yang dihasilkan nHibernate, yang memiliki banyak kolom di SELECT, dengan indeks yang berguna.
sumber
Salah satu alasan untuk lebih memilih
INCLUDE
daripada kolom-kunci jika Anda tidak membutuhkan kolom dalam kunci adalah dokumentasi. Itu membuat indeks yang berkembang jauh lebih mudah di masa depan.Mempertimbangkan contoh Anda:
Indeks itu yang terbaik jika kueri Anda terlihat seperti ini:
Tentu saja Anda tidak boleh memasukkan kolom
INCLUDE
jika Anda bisa mendapatkan manfaat tambahan dari menempatkannya di bagian kunci. Kedua pertanyaan berikut sebenarnya akan lebih sukacol2
kolom di kunci indeks.Mari kita asumsikan ini tidak terjadi dan kita miliki
col2
dalamINCLUDE
klausa karena tidak ada untungnya memiliki di bagian pohon indeks.Maju cepat beberapa tahun.
Anda perlu menyetel kueri ini:
Untuk mengoptimalkan kueri itu, indeks berikut akan bagus:
Jika Anda memeriksa indeks apa yang sudah Anda miliki di tabel itu, indeks Anda sebelumnya mungkin masih ada:
Sekarang Anda tahu itu
Col2
danCol3
bukan bagian dari pohon indeks dan karenanya tidak digunakan untuk mempersempit rentang indeks baca atau untuk memesan baris. Is agak aman untuk ditambahkananother_column
ke akhir bagian kunci indeks (setelahcol1
). Ada sedikit risiko untuk memecahkan apa pun:Indeks itu akan menjadi lebih besar, yang masih memiliki beberapa risiko, tetapi umumnya lebih baik memperpanjang indeks yang sudah ada dibandingkan dengan memperkenalkan yang baru.
Jika Anda akan memiliki indeks tanpa
INCLUDE
, Anda tidak bisa tahu permintaan apa yang akan Anda pecahkan dengan menambahkananother_col
setelahnyaCol1
.Apa yang terjadi jika Anda menambahkan
another_col
antaraCol1
danCol2
? Apakah pertanyaan lain akan terganggu?Ada "manfaat" lain dari
INCLUDE
kolom kunci vs. jika Anda menambahkan kolom itu hanya untuk menghindari mengambilnya dari tabel . Namun, saya menganggap aspek dokumentasi yang paling penting.Untuk menjawab pertanyaan Anda:
Jika Anda menambahkan kolom ke indeks untuk tujuan tunggal agar kolom itu tersedia dalam indeks tanpa mengunjungi tabel, masukkan ke dalam
INCLUDE
klausa.Jika menambahkan kolom ke kunci indeks membawa manfaat tambahan (misalnya untuk
order by
atau karena itu dapat mempersempit rentang indeks baca) menambahkannya ke kunci.Anda dapat membaca diskusi yang lebih panjang tentang ini di sini:
https://use-the-index-luke.com/blog/2019-04/include-columns-in-btree-indexes
sumber
Ada batas ukuran total semua kolom yang diuraikan dalam definisi indeks. Meskipun begitu, saya tidak pernah harus membuat indeks seluas itu. Bagi saya, keuntungan yang lebih besar adalah fakta bahwa Anda dapat mencakup lebih banyak permintaan dengan satu indeks yang menyertakan kolom karena tidak harus didefinisikan dalam urutan tertentu. Pikirkan adalah sebagai indeks dalam indeks. Salah satu contoh adalah StoreID (di mana StoreID adalah selektivitas rendah yang berarti bahwa setiap toko dikaitkan dengan banyak pelanggan) dan kemudian data demografi pelanggan (LastName, FirstName, DOB): Jika Anda hanya menyejajarkan kolom-kolom dalam urutan ini (StoreID, LastName , FirstName, DOB), Anda hanya dapat mencari pelanggan yang Anda tahu StoreID dan LastName secara efisien.
Di sisi lain, mendefinisikan indeks pada StoreID dan termasuk LastName, FirstName, kolom DOB akan membiarkan Anda pada dasarnya melakukan dua pencarian indeks pada StoreID dan kemudian mencari predikat pada salah satu kolom yang disertakan. Ini akan memungkinkan Anda menutupi semua permutasi pencarian yang mungkin selama itu dimulai dengan StoreID.
sumber