Pourquoi l'opérateur d'agrégation utilisé après un balayage d'index unique

15

J'ai une table avec un index unique filtré pour les valeurs non nullables. Dans le plan de requête, il existe l'utilisation de distinct. Y a-t-il une raison à cela?

USE tempdb

CREATE TABLE T1( Id INT NOT NULL  IDENTITY PRIMARY KEY ,F1 INT , F2 INT )
go
CREATE UNIQUE NONCLUSTERED INDEX UK_T1 ON T1 (F1,F2) WHERE F1 IS NOT NULL AND F2 IS NOT NULL 
GO
INSERT INTO  T1(f1,F2) VALUES(1,1),(1,2),(2,1)

SELECT DISTINCT   F1,F2 FROM T1 WHERE F1 IS NOT NULL AND F2 IS NOT NULL 
SELECT  F1,F2 FROM T1 WHERE F1 IS NOT NULL AND F2 IS NOT NULL  

plan de requête: entrez la description de l'image ici

mordechai
la source

Réponses:

15

Il s'agit d'une limitation connue de l'optimiseur de requêtes SQL Server. Il a été signalé à Microsoft, mais l'élément Connect (qui n'est plus disponible) a été fermé. Ne sera pas résolu.

Il y a des conséquences supplémentaires de cette limitation, y compris certaines dont j'ai parlé dans Optimizer Limitations with Filtered Indexes , le résumé est cité ci-dessous:

Cette publication met en évidence deux limitations importantes de l'optimiseur avec des index filtrés:

  • Des prédicats de jointure redondants peuvent être nécessaires pour faire correspondre les index filtrés
  • Les index uniques filtrés ne fournissent pas d'informations d'unicité à l'optimiseur

Dans certains cas, il peut être pratique d'ajouter simplement les prédicats redondants à chaque requête. L'alternative consiste à encapsuler les prédicats implicites souhaités dans une vue non indexée. Le plan de correspondance de hachage dans ce post était bien meilleur que le plan par défaut, même si l'optimiseur devrait être en mesure de trouver le plan de jointure de fusion légèrement meilleur. Parfois, vous devrez peut-être indexer la vue et utiliser des NOEXPANDconseils (requis de toute façon pour les instances Standard Edition). Dans d'autres circonstances encore, aucune de ces approches ne conviendra.

Paul White 9
la source