Satu atau dua indeks?

11

Saya memiliki indeks berikut yang dibuat pada tabel di database saya:

CREATE INDEX [idx_index1]
on [table1]
(col1, col2, col3)

Server menyarankan indeks 'hilang' berikut:

CREATE INDEX [idx_index2]
on [table1]
(col1, col2)
INCLUDE (col3, col4, col5, col6....)

Tampaknya logis bagi saya untuk mengubah definisi indeks yang ada untuk memasukkan kolom yang disarankan, daripada membuat indeks baru yang perlu dipertahankan. Kueri yang memilih pada col1 dan col2 dapat menggunakan index1 sama efektifnya dengan index2. Apakah saya benar atau mungkin saya melewatkan sesuatu?

paH
sumber

Jawaban:

12

Dan memasuki seni strategi tuning kinerja dan pengindeksan ...

Tampaknya logis bagi saya untuk mengubah definisi indeks yang ada untuk memasukkan kolom yang disarankan

Saya akan mengambil penawaran Anda dan menulis definisi indeks ketiga:

create index [idx_index3]
on [table1] (col1, col2, col3)
include (col4, col5, col6....);

Itu harus menjadi CREATE INDEXpernyataan yang sesuai dengan pernyataan yang Anda kutip.

Itu mungkin solusi yang bijaksana, tapi itu tergantung . Berikut adalah beberapa contoh ketika saya mengatakan bahwa itu tergantung.

Jika Anda memiliki beban kerja umum yang sebagian besar terdiri dari kueri seperti ini:

select col1, col2, col3
from table1
where col1 = 1
and col2 = 2
and col3 = 3;

Maka idx_index1indeks Anda akan solid. Sangat sempit, ini adalah indeks yang memenuhi kueri itu tanpa data asing di dalamnya (tidak memperhitungkan definisi indeks yang dikelompokkan, jika ada).

Tetapi jika Anda memiliki beban kerja yang terdiri dari kueri terutama seperti berikut ini:

select co11, col2, col3, col4, col5
from table1
where col1 = 1
and col2 = 2;

Maka idx_index2akan lebih bijak, karena apa yang disebut indeks penutup mencegah kebutuhan untuk pencarian kunci kembali ke indeks berkerumun (atau pencarian RID kembali ke tumpukan). Definisi indeks yang tidak tercakup itu hanya akan mencakup semua data yang dibutuhkan kueri.

Dengan rekomendasi Anda, itu akan sangat cocok untuk permintaan seperti berikut:

select co11, col2, col3, col4, col5
from table1
where col1 = 1
and col2 = 2
and col3 = 3;

idx_index3Rekomendasi Anda akan menjadi indeks penutup yang memenuhi kriteria pencarian untuk permintaan di atas.

Poin yang saya coba sampaikan, adalah dalam pertanyaan terisolasi seperti ini kita tidak bisa menjawab ini secara definitif. Itu semua tergantung pada apa beban kerja umum dan sering. Tentu saja Anda selalu dapat menentukan ketiga indeks ini untuk menangani setiap jenis kueri sampel, tetapi kemudian mempertanyakan pemeliharaan yang akan diperlukan untuk menjaga agar indeks ini diperbarui (pikirkan: INSERT, UPDATE, HAPUS). Itulah overhead indeks.

Anda perlu membedah dan mengevaluasi beban kerja, dan menentukan di mana keunggulan akan terbaik. Jika kueri sampel pertama adalah yang paling umum sejauh ini dieksekusi puluhan kali per detik, dan ada kueri yang sangat jarang seperti kueri sampel ketiga, maka tidak masuk akal untuk mengasapi halaman level daun indeks dengan INCLUDEkolom bukan kunci. Itu semua tergantung pada beban kerja Anda.

Jika Anda memahami strategi pengindeksan yang bijaksana, dan Anda memahami beban kerja Anda yang umum, maka dengan menerapkan keduanya, Anda akan dapat menemukan apa rute terbaik yang harus diambil.

Thomas Stringer
sumber
Saya harus mencernanya sebentar tapi sepertinya ini jawaban yang bagus. Saya menganggap itu salah ketik bahwa 'index3' yang Anda tetapkan memiliki col3 sebagai kolom kesetaraan DAN kolom yang disertakan?
paulH
Yap :-) Tangkapan bagus. Saya sudah mengeditnya.
Thomas Stringer
Belum lagi jika tabel hanya memiliki cols 1-6 cukup konyol untuk mengindeks 1 & 2 dan termasuk 3-5.
Kenneth Fisher
1
@KennethFisher - mengapa itu konyol? Tampaknya hal yang cukup masuk akal untuk dilakukan jika struktur basis data dan beban kerja Anda menjaminnya. Misalnya jika Anda memiliki kueri yang memilih kolom 1-5 berdasarkan nilai kolom 1 dan 2, dan mungkin kolom 6 adalah kolom nvarchar (maks) yang tidak ingin Anda gembungkan indeks Anda.
paulH
1
@ paulH Mungkin ini hanya pendapat saya tetapi pada titik Anda telah menambahkan kolom yang cukup untuk memasukkan bahwa indeks Anda memiliki 90 +% dari kolom Anda dalam tabel Anda telah menggembungkan indeks Anda ke titik bahwa membaca ekstra untuk pergi ke meja itu sendiri tidak terlalu penting. Sekarang tentu saja ada pengecualian .. jika cols 1-5 semuanya int dan col6 adalah varchar (maks) maka saya mungkin melakukannya. Tetapi secara umum saya akan melihat mereka SANGAT hati-hati.
Kenneth Fisher
7

Anda memang benar dan telah menemukan mengapa penting bagi DBA untuk selalu meninjau "saran" yang diajukan oleh DMV indeks yang hilang, dll.

Pertimbangkan bahwa saran yang ditawarkan oleh DMV indeks yang hilang diajukan secara terpisah, artinya SQL Server memutuskan bahwa indeks dari struktur yang direkomendasikan akan menguntungkan permintaan, terlepas dari apa struktur indeks lain yang mungkin sudah ada.

John Sansom
sumber
3

Sedikit lagi, pada salah satu implikasi dari jawaban Thomas:

Dia berkata:

Tentu saja Anda selalu dapat mendefinisikan ketiga indeks ini untuk menangani setiap jenis kueri sampel, tetapi kemudian mempertanyakan pemeliharaan yang akan diperlukan untuk menjaga agar indeks ini diperbarui (pikirkan: INSERT, UPDATE, HAPUS). Itulah overhead indeks.

Jadi, pertanyaan besar lainnya menjadi: seberapa sering tabel diperbarui?

Pertimbangkan dulu contoh tabel yang terus diperbarui, seperti misalnya, ORDERStabel ritel yang mencerminkan aktivitas konsumen situs web ... di sana, Anda ingin berhati-hati tentang memiliki beberapa indeks, karena mereka meningkatkan pekerjaan yang dilakukan oleh pembaruan konstan, dan karenanya terus mempengaruhi kinerja database.

Di sisi lain, pertimbangkan tabel yang hanya diperbarui sebagai bagian dari pengaturan situs web - tabel yang diperbarui SEKALI untuk sebagian besar nilai, dan nilai yang jarang ditambahkan - di sana, perbaruan pelambatan tidak menjadi pertimbangan. Beberapa indeks dapat memperlambat pembangunan kembali & reorg indeks basis data, tetapi selama itu cukup cepat, MERASA GRATIS: jika beberapa indeks mempercepat baca, lakukanlah.

Kasus tengah bisa berupa tabel yang biasanya hanya diperbarui dalam proses batch semalam. Di sana, perbarui perlambatan dari beberapa indeks tidak akan memengaruhi kinerja siang hari - mereka hanya akan memengaruhi (1) waktu yang dibutuhkan, untuk menjalankan pemeliharaan batch malam itu, (2) kinerja setiap proses bersamaan, dan (3) waktu yang dibutuhkan untuk tugas pemeliharaan database seperti reorganisasi indeks. Jadi, selama proses di 3 arena tersebut berjalan cukup cepat untuk Anda ... buat indeks yang mempercepat kueri.

HTH ...

Doug_Ivison
sumber