L'indice non cluster mancante fa già parte dell'indice cluster


9

Sto eseguendo il debug di una query a esecuzione lenta e nel piano di esecuzione viene suggerito un indice non cluster, con 51.6648 Impact. Tuttavia, l'indice non cluster include solo le colonne che sono già nell'indice cluster composito chiave primaria (PK).

Questo potrebbe essere dovuto all'ordine delle colonne nell'indice? cioè se le colonne dell'indice cluster non sono in ordine dal più selettivo al minimo, allora esiste un potenziale per un indice non cluster per migliorare le prestazioni?

Inoltre, l'indice non cluster contiene solo due delle tre colonne PK con la terza aggiunta come colonna inclusa. È includeun altro motivo per cui l'uso dell'indice non cluster potrebbe essere più ottimale?

Di seguito è riportato un esempio delle strutture di tabella con cui sto lavorando:

tavoli-

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 ...)

La tabella Retailer_Relationspresenta il seguente indice PK composito e l'indice suggerito-

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
    )

Risposte:


12

La tabella Retailer_Relations ha il seguente indice PK composito e l'indice suggerito-

Sebbene gli indici mancanti possano essere utili e sicuramente funzionanti, non spenderei troppo tempo sugli indici mancanti, questi suggerimenti vengono creati sul piano di esecuzione stimato, non sul piano di esecuzione effettivo.

Più precisamente, questi suggerimenti sull'indice si basano sul presupposto di ridurre il costo di Query Bucks ™ utilizzato dagli operatori del piano. L'ottimizzatore calcola i costi stimati e aggiunge di conseguenza suggerimenti sull'indice mancanti.

Di conseguenza potrebbero essere molto sbagliati. Se non sei sicuro che possa essere d'aiuto, la cosa migliore da fare è testare la situazione prima e dopo. È possibile farlo aggiungendo l'istruzione SET STATISTICS IO, TIME ON;prima di eseguire la query.

Inoltre, è possibile utilizzare statisticsparser per semplificare la lettura di queste statistiche.

Questo potrebbe essere dovuto all'ordine delle colonne nell'indice?

Ciò è corretto, la creazione dell'indice mancante può migliorare la selettività sulle query, ad esempio se la query è simile alla seguente:

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

o in questo modo:

SELECT  RelatedRetailerID
FROM Retailer_Relations 
ORDER BY
RetailerID,
RelationType;

Il ragionamento alla base di ciò è che entrambi gli indici potrebbero cercare su RetailerID, quella parte non cambierà. Ma cosa succede se vengono applicati filtri / ordini aggiuntivi su RelationType? Sarebbe ovunque nell'indice cluster, come risultato del fatto che è il terzo valore chiave, non il secondo valore chiave. E come sappiamo, è il secondo valore chiave nell'NCI.

Va bene, ma quando o come l'indice non cluster migliorerebbe la query?

Un paio di casi potrebbero essere:

  • Se relationshipType filtra molti valori, l'I / O residuo potrebbe essere elevato, con conseguente possibile necessità dell'indice non cluster (Query # 1)
  • L'ordinamento su due colonne avviene (solo andata) e il gruppo di risultati è grande (query n. 2).
  • Come accennato da @AaronBertrand: se la differenza di dimensioni dell'elemento della configurazione rispetto all'NCI è considerevole, l'aggiunta dell'NCI ridurrà le pagine lette dalle query che ne beneficiano.

Nota laterale NCI

Come nota a margine, l'aggiunta delle colonne chiave all'elenco di inclusione nel tuo NCI non è esattamente necessaria, poiché le colonne chiave CI sono automaticamente incluse in tutti gli indici non cluster.

Puoi scegliere di farlo se non sei sicuro che l'indice cluster rimarrà lo stesso e desideri che la colonna sia sempre inclusa.

Per quanto riguarda la query stessa, se hai aggiunto il piano di esecuzione tramite PasteThePlan , potremmo fornire ulteriori informazioni sull'indicizzazione / miglioramento della query.


analisi

Crea una tabella e aggiungi alcune righe

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

Query n. 1

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

Pianificare senza indice Qui

Mentre sta effettuando una ricerca, sta effettuando una ricerca su RetailerID. Successivamente emette un predicato I / O residuo su RelationType

Aggiungi l'indice

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

Il predicato residuo è sparito, tutto accade in un predicato di ricerca, su entrambe le colonne.

Progetto esecutivo

Con la seconda query, la disponibilità dell'indice aggiunto diventa ancora più ovvia:

SELECT  RelatedRetailerID
FROM Retailer_Relations 
ORDER BY
RetailerID,
RelationType;

Pianificare senza l'indice, con un operatore di ordinamento:

inserisci qui la descrizione dell'immagine

Pianificare con l'indice, l'utilizzo dell'indice rimuove l'operatore di ordinamento

inserisci qui la descrizione dell'immagine


1
Grazie Randi, lo segnerò come risposta ma volevo solo chiedere stai dicendo che il suggerimento sull'indice mancante si basa sul piano di esecuzione stimato? Lo chiedo come viene visualizzato nel Piano di esecuzione effettivo in SS2016.
Fletch,

1
Mi chiedevo se fosse quello che stavi dicendo, grazie per il chiarimento.
Fletch,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.