Dalam penyimpanan berorientasi baris SQL Server, baik indeks clustered dan nonclustered diatur sebagai B tree.
( Sumber Gambar )
Perbedaan utama antara indeks berkerumun dan indeks tidak berkerumun adalah bahwa tingkat daun indeks berkerumun adalah tabel. Ini memiliki dua implikasi.
- Baris pada halaman daun indeks berkerumun selalu berisi sesuatu untuk setiap kolom (tidak jarang) dalam tabel (baik nilai, atau penunjuk ke nilai aktual).
- Indeks berkerumun adalah salinan utama tabel.
Indeks non-cluster juga dapat melakukan poin 1 dengan menggunakan INCLUDE
klausa (Sejak SQL Server 2005) untuk secara eksplisit menyertakan semua kolom non-kunci tetapi mereka adalah representasi sekunder dan selalu ada salinan data lain di sekitar (tabel itu sendiri).
CREATE TABLE T
(
A INT,
B INT,
C INT,
D INT
)
CREATE UNIQUE CLUSTERED INDEX ci ON T(A,B)
CREATE UNIQUE NONCLUSTERED INDEX nci ON T(A,B) INCLUDE (C,D)
Dua indeks di atas akan hampir identik. Dengan halaman indeks tingkat atas yang mengandung nilai untuk kolom kunci A,B
dan halaman tingkat daun berisiA,B,C,D
Hanya ada satu indeks berkerumun per tabel, karena baris data itu sendiri dapat diurutkan hanya dalam satu urutan.
Kutipan di atas dari buku SQL Server online menyebabkan banyak kebingungan
Menurut pendapat saya itu akan menjadi ungkapan yang lebih baik.
Hanya ada satu indeks berkerumun per tabel, karena baris tingkat daun dari indeks berkerumun adalah baris tabel.
Kutipan buku online tidak salah, tetapi Anda harus jelas bahwa "pengurutan" dari kedua indeks non-clustered dan logis adalah logis bukan fisik. Jika Anda membaca halaman pada tingkat daun dengan mengikuti daftar yang ditautkan dan membaca baris pada halaman dalam urutan array slot maka Anda akan membaca baris indeks dalam urutan diurutkan tetapi secara fisik halaman mungkin tidak diurutkan. Kepercayaan umum bahwa dengan indeks berkerumun baris selalu disimpan secara fisik pada disk dalam urutan yang sama dengan kunci indeks salah.
Ini akan menjadi implementasi yang tidak masuk akal. Sebagai contoh jika sebuah baris dimasukkan ke tengah tabel 4GB SQL Server tidak harus menyalin 2GB data dalam file untuk memberikan ruang bagi baris yang baru dimasukkan.
Alih-alih terjadi pemisahan halaman. Setiap halaman pada tingkat daun dari indeks berkerumun dan tidak berkerumun memiliki alamat ( File:Page
) dari halaman berikutnya dan sebelumnya dalam urutan kunci logis. Halaman-halaman ini tidak harus bersebelahan atau berurutan.
misalnya rantai halaman yang ditautkan mungkin 1:2000 <-> 1:157 <-> 1:7053
Ketika terjadi pemisahan halaman, halaman baru dialokasikan dari mana saja di filegroup (baik dari tingkat campuran, untuk tabel kecil, atau tingkat seragam yang tidak kosong milik objek itu atau tingkat seragam yang baru dialokasikan). Ini bahkan mungkin tidak berada di file yang sama jika grup file berisi lebih dari satu.
Tingkat perbedaan urutan dan kedekatan logis dari versi fisik ideal adalah tingkat fragmentasi logis.
Dalam database yang baru dibuat dengan satu file saya menjalankan yang berikut ini.
CREATE TABLE T
(
X TINYINT NOT NULL,
Y CHAR(3000) NULL
);
CREATE CLUSTERED INDEX ix
ON T(X);
GO
--Insert 100 rows with values 1 - 100 in random order
DECLARE @C1 AS CURSOR,
@X AS INT
SET @C1 = CURSOR FAST_FORWARD
FOR SELECT number
FROM master..spt_values
WHERE type = 'P'
AND number BETWEEN 1 AND 100
ORDER BY CRYPT_GEN_RANDOM(4)
OPEN @C1;
FETCH NEXT FROM @C1 INTO @X;
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO T (X)
VALUES (@X);
FETCH NEXT FROM @C1 INTO @X;
END
Kemudian periksa tata letak halaman dengan
SELECT page_id,
X,
geometry::Point(page_id, X, 0).STBuffer(1)
FROM T
CROSS APPLY sys.fn_PhysLocCracker( %% physloc %% )
ORDER BY page_id
Hasilnya ada di mana-mana. Baris pertama dalam urutan tombol (dengan nilai 1 - disorot dengan panah di bawah) ada di hampir halaman fisik terakhir.
Fragmentasi dapat dikurangi atau dihapus dengan membangun kembali atau mengatur ulang indeks untuk meningkatkan korelasi antara tatanan logis dan tatanan fisik.
Setelah berlari
ALTER INDEX ix ON T REBUILD;
Saya mendapat yang berikut
Jika tabel tidak memiliki indeks berkerumun itu disebut heap.
Indeks non-cluster dapat dibangun di atas heap atau indeks cluster. Mereka selalu berisi pelacak baris kembali ke tabel dasar. Dalam kasus tumpukan ini adalah pengidentifikasi baris fisik (rid) dan terdiri dari tiga komponen (File: Halaman: Slot). Dalam kasus indeks Clustered locator baris adalah logis (kunci indeks berkerumun).
Untuk kasus yang terakhir jika indeks non-cluster sudah secara alami menyertakan kolom kunci CI baik sebagai kolom kunci NCI atau INCLUDE
kolom -d maka tidak ada yang ditambahkan. Kalau tidak, kolom kunci CI yang hilang diam-diam ditambahkan ke NCI.
SQL Server selalu memastikan bahwa kolom kunci unik untuk kedua jenis indeks. Mekanisme di mana ini diberlakukan untuk indeks tidak dinyatakan sebagai unik berbeda antara kedua jenis indeks.
Indeks yang dikelompokkan mendapat uniquifier
tambahan untuk setiap baris dengan nilai kunci yang menduplikasi baris yang ada. Ini hanya bilangan bulat naik.
Untuk indeks yang tidak berkerumun yang tidak dideklarasikan sebagai SQL Server unik, diam-diam menambahkan pencari baris ke kunci indeks yang tidak dikelompokkan. Ini berlaku untuk semua baris, bukan hanya yang sebenarnya duplikat.
Nomenklatur clustered vs non clustered juga digunakan untuk indeks toko kolom. Makalah Peningkatan ke Toko Kolom SQL Server menyatakan
Meskipun kolom menyimpan data tidak benar-benar "berkerumun" pada kunci apa pun, kami memutuskan untuk mempertahankan konvensi SQL Server tradisional merujuk ke indeks primer sebagai indeks berkerumun.