Perché SQL Server non ha richieste di indice mancanti nei DMV o nei piani di query?


14

Ho un database SQL Server in cui le query sono piuttosto lente e ci sono molti blocchi e blocchi.

Quando guardo i DMV dell'indice mancanti e i piani di query, non ci sono suggerimenti.

Perché?

Risposte:


17

Ci sono molti motivi per cui potresti non avere richieste di indice mancanti!

Esamineremo alcuni dei motivi in ​​modo più dettagliato e parleremo anche di alcuni dei limiti generali della funzione.

Limitazioni generali

Innanzitutto, da: Limitazioni della caratteristica degli indici mancanti :

  • Non specifica un ordine per le colonne da utilizzare in un indice.

Come indicato in queste domande e risposte: In che modo SQL Server determina l'ordine delle colonne chiave nelle richieste di indice mancanti? , l'ordine delle colonne nella definizione dell'indice è dettato dal predicato Equality vs Inequality, quindi dalla posizione ordinale della colonna nella tabella.

Non ci sono ipotesi sulla selettività e potrebbe esserci un ordine migliore disponibile. È il tuo lavoro per capirlo.

Indici speciali

Le richieste di indice mancanti non coprono anche gli indici "speciali", come:

  • clustered
  • filtrato
  • Partitioned
  • compressa
  • XML-ed
  • Spatial-ed
  • Columnstore-d
  • Visualizzazione indicizzata

Quali colonne sono considerate?

Le colonne chiave dell'indice mancanti vengono generate dalle colonne utilizzate per filtrare i risultati, come quelli in:

  • join
  • Dove la clausola

Le colonne mancanti dell'indice incluso sono generate dalle colonne richieste dalla query, come quelle in:

  • SELEZIONARE
  • RAGGRUPPARE PER
  • ORDINATO DA

Anche se abbastanza spesso, le colonne che stai ordinando o raggruppando possono essere utili come colonne chiave. Questo risale a una delle limitazioni:

  • Non ha lo scopo di ottimizzare una configurazione di indicizzazione.

Ad esempio, questa query non registra una richiesta di indice mancante, anche se l'aggiunta di un indice su LastAccessDate eviterebbe la necessità di ordinare (e versare sul disco).

SELECT TOP (1000) u.DisplayName
FROM dbo.Users AS u
ORDER BY u.LastAccessDate DESC;

NOCCIOLINE

Né questa query di raggruppamento su Posizione.

SELECT TOP (20000) u.Location
FROM dbo.Users AS u
GROUP BY u.Location

NOCCIOLINE

Non sembra molto utile!

Bene, sì, ma è meglio di niente. Pensa alle richieste di indice mancanti come un bambino che piange. Sai che c'è un problema, ma spetta a te da adulto capire qual è il problema.

Non mi hai ancora detto perché non li ho, però ...

Rilassati, tesoro. Ci stiamo arrivando.

Bandiere di traccia

Se si abilita TF 2330 , le richieste di indice mancanti non verranno registrate. Per scoprire se hai abilitato questo, esegui questo:

DBCC TRACESTATUS;

Ricostruzioni dell'indice

La ricostruzione degli indici eliminerà le richieste di indice mancanti. Quindi prima di andare Hi-Ho-Silver-Away ricostruendo ogni indice nel secondo in cui si intrufola una iota di frammentazione, pensa alle informazioni che stai cancellando ogni volta che lo fai.

Potresti anche pensare al motivo per cui la deframmentazione degli indici non aiuta , comunque. A meno che tu non stia usando Columnstore .

Aggiunta, rimozione o disabilitazione di indici

L'aggiunta, la rimozione o la disabilitazione di un indice cancellerà tutte le richieste di indice mancanti per quella tabella. Se stai lavorando su diverse modifiche all'indice sulla stessa tabella, assicurati di scriverle tutte prima di apportare.

Piani Triviali

Se un piano è abbastanza semplice e la scelta dell'accesso all'indice è abbastanza ovvia e il costo è abbastanza basso, otterrai un piano banale.

Ciò significa effettivamente che l'ottimizzatore non deve prendere decisioni basate sui costi.

Via Paul White :

I dettagli di quali tipi di query possono beneficiare del piano di valutazione cambiano frequentemente, ma cose come join, sottoquery e predicati di disuguaglianza generalmente impediscono questa ottimizzazione.

Quando un piano è banale, non vengono esplorate fasi di ottimizzazione aggiuntive e non vengono richiesti indici mancanti .

Scopri la differenza tra queste query e i loro piani :

SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2;

SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2
AND 1 = (SELECT 1);

NOCCIOLINE

Il primo piano è banale e non viene mostrata alcuna richiesta. Ci possono essere casi in cui i bug impediscono la visualizzazione di indici mancanti nei piani di query; tuttavia, in genere vengono registrati in modo più affidabile nei DMV indice mancanti.

SARGability

I predicati in cui l'ottimizzatore non sarebbe in grado di utilizzare un indice in modo efficiente anche con un indice può impedire che vengano registrati.

Le cose che generalmente non sono SARGable sono:

  • Colonne avvolte in funzioni
  • Colonna + SomeValue = SomePredicate
  • Colonna + AnotherColumn = SomePredicate
  • Colonna = @Variable OR @Variable IS NULL

Esempi:

SELECT *
FROM dbo.Users AS u
WHERE ISNULL(u.Age, 1000) > 1000;


SELECT *
FROM dbo.Users AS u
WHERE DATEDIFF(DAY, u.CreationDate, u.LastAccessDate) > 5000


SELECT *
FROM dbo.Users AS u
WHERE u.UpVotes + u.DownVotes > 10000000


DECLARE @ThisWillHappenWithStoredProcedureParametersToo NVARCHAR(40) = N'Eggs McLaren'
SELECT *
FROM dbo.Users AS u
WHERE u.DisplayName LIKE @ThisWillHappenWithStoredProcedureParametersToo 
      OR @ThisWillHappenWithStoredProcedureParametersToo IS NULL;

Nessuna di queste query registra richieste di indice mancanti. Per ulteriori informazioni su questi, controlla i seguenti collegamenti:

Hai già un indice OK

Prendi questo indice:

CREATE INDEX ix_whatever ON dbo.Posts(CreationDate, Score) INCLUDE(OwnerUserId);

Sembra a posto per questa query:

SELECT p.OwnerUserId, p.Score
FROM dbo.Posts AS p
WHERE p.CreationDate >= '20070101'
AND   p.CreationDate < '20181231'
AND   p.Score >= 25000
AND 1 = (SELECT 1)
ORDER BY p.Score DESC;

Il piano è un semplice cerca ...

NOCCIOLINE

Ma poiché la colonna chiave principale è per il predicato meno selettivo, finiamo per fare più lavoro di quanto dovremmo:

Tabella "Messaggi". Conteggio scansione 13, letture logiche 136890

Se cambiamo l'ordine delle colonne della chiave di indice, facciamo molto meno lavoro:

CREATE INDEX ix_whatever ON dbo.Posts(Score, CreationDate) INCLUDE(OwnerUserId);

NOCCIOLINE

E significativamente meno legge:

Tabella "Messaggi". Conteggio scansioni 1, letture logiche 5

SQL Server sta creando indici per te

In alcuni casi, SQL Server sceglierà di creare un indice al volo tramite uno spool di indice. Quando è presente uno spool di indice, una richiesta di indice mancante non sarà. Sicuramente aggiungere tu stesso l'indice potrebbe essere una buona idea, ma non contare su SQL Server che ti aiuta a capirlo.

NOCCIOLINE

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.