Eksik Kümelenmemiş Dizin zaten Kümelenmiş Dizin'in bir parçası


9

Yavaş çalışan bir sorgu hata ayıklama ve yürütme planı 51.6648 etkisi ile kümelenmemiş bir dizin önerilir. Ancak, kümelenmemiş dizin yalnızca zaten Birincil Anahtar (PK) Kompozit Kümelenmiş Dizini'nde bulunan sütunları içerir.

Bu, dizindeki sütunların sırası nedeniyle olabilir mi? örneğin, kümelenmiş dizindeki sütunlar en seçici olandan en az düzeye doğru değilse, kümelenmemiş bir dizinin performansı artırma potansiyeli var mıdır?

Ayrıca, kümelenmemiş dizin, üç PK sütunundan yalnızca ikisini içerir; üçüncü sütun dahil edilen sütun olarak eklenir. Mi includeolmayan kümelenmiş indeksi kullanımı daha optimum olabilir başka bir nedeni?

Aşağıda çalıştığım tablo yapılarına bir örnek:

tablolardan bulunabilir

Retailers (
    RetailerID int PK, 
    name ...)

Retailer_Relation_Types (
    RelationType smallint PK, 
    Description nvarchar(50) ...)

Retailer_Relations (
    RetailerID int PK FK, 
    RelatedRetailerID int PK FK, 
    RelationType smallint PK FK, 
    CreatedOn datetime ...)

Tablo Retailer_Relationsaşağıdaki bileşik PK dizinine ve önerilen dizin-

CONSTRAINT PK_Retailer_Relations 
PRIMARY KEY CLUSTERED (
    RetailerID ASC, 
    RelatedRetailerID ASC, 
    RelationType ASC
    ) ON [PRIMARY]

CREATE NONCLUSTERED INDEX <NameOfIndex> 
ON Retailer_Relations (
    RetailerID, 
    RelationType
    ) 
INCLUDE (
    RelatedRetailerID
    )

Yanıtlar:


12

Retailer_Relations tablosu aşağıdaki bileşik PK dizinine ve önerilen dizin-

Eksik dizinler yardımcı olabilir ve kesinlikle işe yarayabilirken, eksik dizinlere çok fazla zaman harcamazdım, bu ipuçları gerçek yürütme planında değil, tahmini yürütme planında yaratılır.

Daha kesin olarak, bu indeks ipuçları, plandaki operatörler tarafından kullanılan Query Bucks ™ maliyetinin düşürülmesi öncülüne dayanmaktadır. Optimize edici, tahmini maliyetleri hesaplar ve buna göre eksik indeks ipuçlarını ekler.

Sonuç olarak çok yanlış olabilirler. Eğer yardım edip etmeyeceğinden emin değilseniz, yapılacak en iyi şey durumu öncesi ve sonrası test etmektir. SET STATISTICS IO, TIME ON;Sorguyu çalıştırmadan önce deyimi ekleyerek bunu yapabilirsiniz .

Ayrıca şunu kullanabilirsiniz statisticsparser daha kolay bu istatistikleri okunmasını sağlayacak şekilde.

Bu, dizindeki sütunların sırası nedeniyle olabilir mi?

Doğru, eksik dizini oluşturmak sorgularda seçiciliği artırabilir, örneğin sorgunuz şöyle görünürse:

SELECT  RelatedRetailerID
FROM Retailer_Relations 
WHERE
RetailerID = 5 AND
RelationType = 20;

ya da bunun gibi:

SELECT  RelatedRetailerID
FROM Retailer_Relations 
ORDER BY
RetailerID,
RelationType;

Bunun ardında yatan neden, her iki indeksin RetailerID üzerinde arama yapabilmesidir, bu kısım değişmeyecektir. Peki RelationType üzerinde fazladan filtreler / sıralamalar uygulanırsa ne olur? Kümelenmiş dizindeki her yerde olur, bunun sonucunda ikinci anahtar değeri değil, üçüncü anahtar değeri olur. Ve bildiğimiz gibi, bu NCI'deki ikinci anahtar değerdir.

Tamam, ancak kümelenmemiş dizin sorguyu ne zaman veya nasıl iyileştirir?

Birkaç vaka olabilir:

  • RelationType çok fazla değeri filtreliyorsa, kalan G / Ç yüksek olabilir ve bu da kümelenmemiş dizinin olası gereksinimine neden olabilir (Sorgu # 1)
  • İki sütunda sıralama yapılır (Tek yön) ve sonuç kümesi büyüktür (Sorgu # 2).
  • @AaronBertrand'ın belirttiği gibi: NCI ile karşılaştırıldığında CI boyut farkı önemli miktarda ise, NCI eklemek, bundan yararlanan sorgular tarafından okunan sayfaları azaltacaktır.

NCI Yan notu

Bir yan not olarak, CI anahtar sütunları otomatik olarak tüm Kümelenmemiş dizinlere dahil edildiğinden, anahtar sütunları NCI'nizdeki dahil listesine eklemek tam olarak gerekli değildir.

Kümelenmiş dizinin aynı kalacağından emin değilseniz ve sütunun her zaman dahil edilmesini istiyorsanız bunu yapmayı tercih edebilirsiniz.

Sorgunun kendisi ile ilgili olarak, PasteThePlan üzerinden yürütme planını eklediyseniz , sorguyu indeksleme / iyileştirme hakkında biraz daha bilgi verebiliriz.


Test yapmak

Tablo oluştur ve bazı satırlar ekle

CREATE TABLE Retailer_Relations (
    RetailerID int , 
    RelatedRetailerID int , 
    RelationType smallint, 
    CreatedOn datetime,
    CONSTRAINT PK_Retailer_Relations 
PRIMARY KEY CLUSTERED (
    RetailerID ASC, 
    RelatedRetailerID ASC, 
    RelationType ASC
    ) ON [PRIMARY])


    DECLARE @I Int = 1
    WHILE @I < 1000
    BEGIN
    INSERT INTO Retailer_Relations(RetailerID,RelatedRetailerID,RelationType,CreatedOn)
    VALUES(@I,@I,@I,GETDATE()
    )
    set @I += 1
    END

Sorgu # 1

    SELECT  RelatedRetailerID
FROM Retailer_Relations 
WHERE
RetailerID = 5 AND
RelationType = 20;

İndeksi olmadan Planı İşte

Bir arama yaparken, RetailerID için bir arama yapıyor. Daha sonra RelationType üzerinde artık bir G / Ç yüklemesi yayınlıyor

Dizini ekle

CREATE NONCLUSTERED INDEX IX_TEST
ON Retailer_Relations (
    RetailerID, 
    RelationType
    ) 
INCLUDE (
    RelatedRetailerID
    )

Kalan yüklem ortadan kalkmıştır, her şey her iki sütunda bir arama yükleminde gerçekleşir.

Yürütme planı

İkinci sorgu ile, eklenen dizin yardımı daha da belirgin hale gelir:

SELECT  RelatedRetailerID
FROM Retailer_Relations 
ORDER BY
RetailerID,
RelationType;

Sıralama operatörü ile dizin olmadan planlama yapın:

resim açıklamasını buraya girin

Dizin kullanarak planlayın, dizini kullanarak sıralama operatörünü kaldırır

resim açıklamasını buraya girin


1
Teşekkürler Randi, bunu cevap olarak işaretleyeceğim ama sadece Eksik Endeks önerisinin Tahmini Yürütme Planına dayandığını mı söylemek istiyorsunuz? Bunu SS2016'daki Gerçek Yürütme Planında göründüğü için soruyorum.
Fletch

1
Söylediğin bu mu diye merak ettim, açıkladığın için teşekkürler.
Fletch
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.