Haruskah saya menggunakan banyak indeks bidang tunggal, alih-alih indeks multi kolom tertentu?

35

Pertanyaan ini adalah tentang efektivitas teknik pengindeksan SQL Server. Saya pikir ini dikenal sebagai "persimpangan indeks".

Saya sedang bekerja dengan aplikasi SQL Server (2008) yang sudah ada yang memiliki sejumlah masalah kinerja dan stabilitas. Para pengembang melakukan beberapa hal aneh dengan pengindeksan. Saya tidak bisa mendapatkan tolok ukur konklusif tentang masalah ini, saya juga tidak dapat menemukan dokumentasi yang benar-benar bagus di internet.

Ada banyak kolom yang bisa dicari di sebuah tabel. Pengembang membuat indeks kolom tunggal pada SETIAP kolom yang dapat dicari. Teorinya adalah bahwa SQL Server akan dapat menggabungkan (berpotongan) masing-masing indeks ini untuk secara efisien mengakses tabel di sebagian besar keadaan. Ini adalah contoh sederhana (tabel sebenarnya memiliki lebih banyak bidang):

CREATE TABLE [dbo].[FatTable](
    [id] [bigint] IDENTITY(1,1) NOT NULL,
    [col1] [nchar](12) NOT NULL,
    [col2] [int] NOT NULL,
    [col3] [varchar](2000) NOT NULL, ...

CREATE NONCLUSTERED INDEX [IndexCol1] ON [dbo].[FatTable]  ( [col1] ASC )
CREATE NONCLUSTERED INDEX [IndexCol2] ON [dbo].[FatTable] ( [col2] ASC )

select * from fattable where col1 = '2004IN' 
select * from fattable where col1 = '2004IN' and col2 = 4

Saya pikir beberapa indeks kolom yang ditargetkan untuk kriteria pencarian jauh lebih baik, tetapi saya mungkin salah. Saya telah melihat rencana permintaan yang menunjukkan SQL Server melakukan pencocokan hash pada dua indeks pencarian. Mungkin ini masuk akal ketika Anda tidak tahu bagaimana tabel dicari? Terima kasih.

RaoulRubin
sumber
@brentozar memiliki video yang bagus tentang indeks yang patut ditonton: brentozar.com/sql-server-training-videos/…
DForck42

Jawaban:

38

Yang Anda butuhkan meliputi indeks, yaitu. indeks yang dapat memenuhi permintaan sendiri. Tetapi indeks 'mencakup' memiliki satu masalah: itu mencakup permintaan tertentu . Jadi untuk mengembangkan strategi pengindeksan yang baik, Anda perlu memahami beban kerja Anda: pertanyaan apa yang menghantam basis data, mana yang penting dan mana yang tidak, seberapa sering setiap jenis kueri dijalankan, dll. Dll. Kemudian Anda menyeimbangkan ini terhadap biaya menulis dan memperbarui setiap indeks, dan di sana Anda memiliki strategi pengindeksan. Jika suara rumit itu adalah karena itu adalah rumit.

Namun Anda dapat menerapkan beberapa aturan praktis. MSDN mencakup dasar-dasarnya dengan cukup baik:

Ada juga banyak artikel yang dikontribusikan oleh komunitas, misalnya. Rekaman Webcast - Penghargaan DBA Darwin: Edisi Indeks .

Dan untuk menjawab pertanyaan Anda secara khusus: indeks terpisah pada setiap kolom dapat berfungsi, asalkan setiap kolom memiliki selektivitas tinggi (banyak nilai berbeda, setiap nilai hanya muncul beberapa kali dalam database). Paket akses yang dihasilkan menggunakan hash join antara dua pemindaian rentang indeks biasanya bekerja dengan baik. Kolom dengan selektivitas rendah (beberapa nilai berbeda, setiap nilai muncul berkali-kali dalam database) tidak masuk akal untuk diindeks sendiri, pengoptimal kueri hanya akan mengabaikannya. Namun, kolom selektivitas rendah sering kali membuat kunci komposit yang baik ketika dipasangkan dengan kolom selektivitas tinggi.

Remus Rusanu
sumber
Remus terima kasih. Saya bertanya-tanya tentang keuntungan relatif dari membuat indeks multi-kolom yang ditargetkan (dan termasuk), vs menggunakan indeks terpisah. Jika "berfungsi cukup baik" cukup baik, mungkin tidak apa-apa. (Akan membuang indeks pada bidang selektivitas rendah). Teknik ini akan membantu ketika kita tidak memiliki akses ke basis data produksi, dan tidak dapat menargetkan indeks kita untuk penggunaan aktual.
RaoulRubin