Come indicizzare le domande sulla disuguaglianza?


10

Ho una query che esclude i dati in base al valore di una colonna float

select * 
from My_Table
where my_Float_column != 0 and my_Float_column is not null

Non voglio indicizzare un tipo float se posso farne a meno. Il piano di esecuzione sarebbe abbastanza intelligente da utilizzare un indice filtrato come il seguente (dove sto indicizzando solo i valori 0 e null) per aumentare le prestazioni?

CREATE NONCLUSTERED INDEX IX_My_Table_Float_Filtered
    ON My_Table (my_Float_column)
    WHERE my_Float_column = 0 or my_Float_column is null

Risposte:


11

Il piano di esecuzione sarebbe abbastanza intelligente da utilizzare un indice filtrato come il seguente (dove sto indicizzando solo i valori 0 e null) per aumentare le prestazioni?

No. Non esiste un supporto diretto in SQL Server per il tipo di rifiuto di riga per singolo operatore che sembra avere in mente.

Parlando più in generale, l'indice filtrato non è direttamente utile per la query data e non è comunque una definizione di filtro indice valida. È possibile invece creare una vista indicizzata contenente tali predicati, ma non sarebbe comunque utile come modo per individuare le righe per la query di destinazione. È possibile riscrivere la query per utilizzare la vista indicizzata per escludere le righe recuperate con una scansione completa separata, ma è difficile vedere come sarebbe una buona idea in generale.

Il più vicino che potresti ottenere sarebbe probabilmente una scansione della vista indicizzata che popola un filtro bitmap, con quel filtro applicato come parte di una scansione completa della tabella di destinazione. Potrebbe essere difficile ottenere questa forma di piano di query in modo affidabile.

È inoltre possibile utilizzare una colonna calcolata persistente indicizzata utilizzando CASEun'espressione, ma ciò richiederebbe di nuovo riscrivere la query originale e richiedere spazio per ogni riga della tabella, più l'indice.

Dalle informazioni fornite, sembra che il meglio che puoi fare sia definire l'indice come:

CREATE NONCLUSTERED INDEX IX_dbo_My_Table__Float_Filtered
ON dbo.My_Table (my_Float_column)
WHERE 
    my_Float_column <> 0 
    AND my_Float_column IS NOT NULL;
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.