Kedua tabel memiliki struktur yang sama dan baris 19972 di setiap tabel. untuk mempraktekkan pengindeksan, saya membuat kedua tabel memiliki struktur yang sama dan dibuat
clustered index on persontb(BusinessEntityID)
dan
nonclustered index on Persontb_NC(BusinessEntityId)
dan struktur tabel
BusinessEntityID int
FirstName varchar(100)
LastName varchar(100)
-- Nonclusted key on businessentityid takes 38%
SELECT BusinessEntityId from Persontb_NC
WHERE businessentityid BETWEEN 400 AND 4000
-- CLustered key businessentityid takes 62%
SELECT BusinessEntityId from persontb
WHERE businessentityid BETWEEN 400 AND 4000
Mengapa indeks clustered membutuhkan 62% dan non clustered 38%?
Jawaban:
Ya indeks berkerumun memiliki baris lebih sedikit per halaman daripada indeks nonkluster karena halaman daun dari indeks berkerumun harus menyimpan nilai untuk dua kolom lainnya (
FirstName
danLastName
).Halaman daun NCI hanya menyimpan
BusinessEntityId
nilai dan pelacak baris (RID jika tabelnya adalah tumpukan atau kunci CI sebaliknya).Jadi perkiraan biaya mencerminkan jumlah pembacaan dan persyaratan IO yang lebih besar.
Jika Anda menyatakan NCI sebagai
maka itu akan mirip dengan indeks berkerumun.
sumber
Indeks Clustered tidak hanya berisi data dari indeks kolom aktif, tetapi juga data dari semua kolom lainnya. (Hanya ada satu indeks berkerumun per tabel)
Nonclustered index hanya berisi data dari kolom yang diindeks, dan sebuah pointer row_id ke tempat data lainnya berada.
Oleh karena itu indeks nonclustered khusus ini lebih ringan dan lebih sedikit membaca diperlukan untuk memindai / mencari melalui itu dan permintaan khusus ini akan bekerja lebih cepat.
Namun, sudahkah Anda mencoba untuk mengambil FirstName dan LastName juga, itu akan berbeda dan indeks cluster harus berkinerja lebih baik.
sumber
Persentase antara rencana kueri tidak ada artinya untuk dibandingkan secara langsung. Anda harus membandingkan permintaan untuk memiliki perbandingan yang valid. Selain itu, jumlah baris kecil memiliki kecenderungan untuk menyembunyikan perbedaan kinerja antara strategi pengindeksan. Dengan meningkatkan jumlah baris menjadi 10 juta, Anda dapat memperoleh gambaran yang lebih jelas tentang perbedaan kinerja.
Ada skrip sampel yang membuat 3 tabel, dua Anda dari atas, dan yang ketiga dengan indeks berkerumun dan tidak berkerumun.
Isi tabel dengan 10 juta baris
Kita dapat menggunakan sys.dm_db_index_physical_stats untuk melihat ukuran pada disk indeks.
Dan hasilnya:
Indeks clustered T1 adalah sekitar 1,6 GB. Indeks non-clustered T2 adalah 170 MB (penghematan 90% dalam IO). Indeks non-cluster T3 adalah 97 MB, atau sekitar 95% lebih sedikit IO daripada T1.
Jadi, berdasarkan dari IO yang diperlukan, rencana kueri asli seharusnya lebih sesuai 10% / 90%, bukan 38% / 62%. Juga, karena indeks non-cluster cenderung cocok sepenuhnya dalam memori, perbedaannya mungkin lebih besar lagi, karena disk IO sangat mahal.
sumber
10%/90%
sosok Anda lebih akurat daripada38%/62%
. String dengan panjang antara 100 dan 200 tentu akan menjadi perkiraan ruang terlalu tinggi untuk pasangan nama depan / nama belakang sehingga Anda akan memiliki kepadatan halaman yang lebih rendah daripada OP. Ketika saya mencoba terhadap data contoh Anda, perkiraan biaya muncul 87% / 13% .data_pages
disys.allocation_units
. Anda dapat melihat ini dariCREATE TABLE T1(C INT);CREATE TABLE T2(C INT);UPDATE STATISTICS T1 WITH PAGECOUNT = 1;UPDATE STATISTICS T2 WITH PAGECOUNT = 100
kemudian membandingkan perkiraan biayaSELECT * FROM T1;SELECT * FROM T2;