Başlıca Hususlar
Yığınlar için bir, kümelenmiş masalar için bir artı avantaj ve her iki şekilde de olabilecek üçüncü bir husus görüyorum.
Bir yığın size bir dolaylı katman kazandırır. Dizinler, doğrudan (gerçekten de değil, ama mümkün olduğunca doğrudan) bir disk konumuna işaret eden satır kimliklerini içerir. Bu nedenle, bir yığına karşı bir endeks araştırması, kümelenmemiş bir endeksin araştırmasının yaklaşık olarak kümelenmiş bir masanın yarısına mal olması gerekir.
Kümelenmiş bir dizin (neredeyse) serbest bir dizin sayesinde kendi başına sıralanır. Kümelenme endeksi, verinin fiziksel sırasına göre yansıtıldığından, elbette, hangisi saklamak zorunda kaldığınız, gerçek verinin üstüne nispeten az yer kaplar. Fiziksel olarak sipariş edildiğinden, bu endekse karşı bir aralık taraması başlangıç noktasına gidebilir ve daha sonra bitiş noktasına kadar verimli bir şekilde fermuarlayabilir.
Yığınlardaki endeksler, 64 bit olan RID'leri referans alır. Belirtildiği gibi, sigara kümelenmiş daha küçük (32-bit olabilir kümelenmiş tablo referans kümeleme anahtarı, ilgili indisleri INT
), aynı (64-bit BIGINT
), ya da daha büyük (bir 48-bit DATETIME2()
artı bir 32-bit INT
, veya 128 bitlik bir GUID). Açıkçası, daha geniş bir referans daha büyük ve daha pahalı endeksler için yapar.
Uzay gereksinimleri
Bu iki tabloyla birlikte:
CREATE TABLE TmpClustered
(
ID1 INT NOT NULL,
ID2 INT NOT NULL
)
ALTER TABLE TmpClustered ADD CONSTRAINT PK_Tmp1 PRIMARY KEY CLUSTERED (ID1)
CREATE UNIQUE INDEX UQ_Tmp1 ON TmpClustered (ID2)
CREATE TABLE TmpNonClustered
(
ID1 INT NOT NULL,
ID2 INT NOT NULL
)
ALTER TABLE TmpNonClustered ADD CONSTRAINT PK_Tmp2 PRIMARY KEY NONCLUSTERED (ID1)
CREATE UNIQUE INDEX UQ_Tmp2 ON TmpNonClustered (ID2)
... her biri 8,7 M kayıtlarla dolduruldu, her ikisi için de gereken alan 150 MB idi; Kümelenmiş tablonun indeksleri için 120 MB, kümelenmemiş tablonun indeksleri için 310 MB. Bu, kümelenmiş endeksin bir RID'den daha dar olduğunu ve kümelenme endeksinin çoğunlukla bir "freebie" olduğunu yansıtmaktadır. Benzersiz endeksler olmadan, ID2
kümelenmemiş tablo için (beklendiği şekilde yarısı) gerekli alan, kümelenmemiş PK için yalnızca 150 KB - hiçbir şeye yakın olmayan, gerekli alan boşluğu düşer .
Bu nedenle, 32 bitlik bir alanın 32 bitlik bir alana sahip kümelenmiş bir tabloda 32 bitlik bir alandaki kümelenmemiş bir dizini 120 MB aldı, bir 64 bitlik bir yığında 32 bitlik bir alanın bir dizini RID (toplam 96 bit, nominal olarak) 155 MB aldı,% 50 artıştan biraz daha az, birisinin 64-bit'den 96-bit anahtarlara geçmesini beklerdi, ancak elbette boyuttaki etkin farkı azaltan genel gider var.
İki tabloyu doldurmak ve dizinlerini oluşturmak her tablo için aynı miktarda zaman aldı. Taramaları veya aramaları içeren basit testler gerçekleştirdiğimde, tablolar arasında, yararlı bir şekilde bağlanmış gbn'ye sahip Microsoft teknik incelemesiyle eşleşen önemli bir performans farkı bulamadım. Bahsedilen makale yüksek eşzamanlı erişim için önemli bir fark göstermektedir; Bunun neden olduğunu bilmiyorum, umarım yüksek hacimli OLTP sistemlerine sahip benden daha fazla deneyime sahip biri bize söyleyebilir.
~ 40 bayt rastgele değişken uzunlukta veri eklemek, bu denkliği büyük ölçüde değiştirmedi. INT
S'yi geniş UUID'lerle değiştirmek de olmadı (her tablo aynı ölçüde yavaşlatıldı). Kilometreniz değişebilir, ancak çoğu durumda bir endeksin mevcut olup olmadığı ne türden daha önemlidir.
Bitler ve Parçalar
Kümelenmemiş bir dizine karşı aralık taraması yapmak - ya tablo bir yığın ya da dizin kümelenmiş dizin olmadığından - dizini taramayı ve ardından her vuruş için tabloya karşı bir arama yapmayı içerir. Bu çok pahalı olabilir, bu nedenle sadece tabloyu taramak bazen daha ucuz olabilir. Bununla birlikte, bunun üzerinde bir kaplama endeksi ile çalışabilirsiniz. Bu, tablonuzu kümelemeniz veya kullanmamanız durumunda geçerlidir.
@Gbn'nin işaret ettiği gibi, bir yığını sıkıştırmanın basit bir yolu yoktur. Bununla birlikte, tablonuz zamanla kademeli olarak artarsa - çok yaygın bir durum - silme tarafından boşaltılan alanın yeni verilerle doldurulması nedeniyle çok az atık olacaktır.
Gördüğüm yığın-küme tablo tartışmalarının birçoğu, endeksleri olmayan bir yığının, her zaman bir tablo taraması gerektirdiği için kümelenmiş bir tablonun gerisinde kaldığına dair meraklı bir strawman tartışması yapar. Bu kesinlikle doğrudur, ancak daha anlamlı bir karşılaştırma "büyük iyi dizine alınmış kümelenmiş masa" ve "büyük iyi dizine yerleştirilmiş yığın." Masanız çok küçükse veya her zaman masa taraması yapacaksınız, o zaman kümelemek veya yapmamanız önemli değil.
Kümelenmiş bir tablodaki her bir dizin kümeleme dizinine başvuruda bulunduğundan, bunlar tüm kapsayan dizinleri etkiler. Dizine alınmış bir sütuna ve kümelenme sütununa / sütunlarına başvuran bir sorgu, herhangi bir tablo araması olmadan bir dizin taraması yapabilir. Kümelenme endeksiniz sentetik bir anahtarsa bu genellikle değerli değildir, ancak yine de almanız gereken bir işletme anahtarıysa, hoş bir özelliktir.
TL; DR
Veri depolama görevlisiyim, OLTP uzmanı değilim. Aslında, tablolarda neredeyse her zaman, genellikle bir tarih alanı olmak üzere aralık taramalarına ihtiyaç duyması muhtemel olan alanda bir kümeleme indeksi kullanıyorum. Boyut tabloları için PK üzerine kümeliyim, böylece birleşme olaylarının olgu tablolarına karşı koyulması gerekiyor.
Kümelenme endekslerini kullanmak için birkaç neden vardır, ancak bu nedenlerden hiçbiri geçerli değilse, genel gider buna değmeyebilir. Evrensel olarak kümelenmiş dizinleri kullanan insanların arkasında çok fazla "her zaman bu şekilde yaptık" ve "en iyi uygulama" olduğundan şüpheleniyorum. Her iki deneyin sizin veri ve senin yük ve en iyi olanı.