Je pense à une situation où j'ai deux colonnes à haute densité mais ces colonnes ne sont pas indépendantes.
Définition
Voici la définition de la table que j'ai créée à des fins de test.
CREATE TABLE [dbo].[StatsTest](
[col1] [int] NOT NULL, --can take values 1 and 2 only
[col2] [int] NOT NULL, --can take integer values from 1 to 4 only
[col3] [int] NOT NULL, --integer. it has not relevance just to ensure that each row is different
[col4] AS ((10)*[col1]+[col2]) --a computed column ensuring that if two rows have different values in col1 or col2 have different values in col4
) ON [PRIMARY]
Les données
Les données de l'expérience sont les suivantes
col1 col2 col3 col4
1 1 1 11
1 2 2 12
1 2 3 12
1 3 4 13
1 3 5 13
1 3 6 13
1 4 7 14
1 4 8 14
1 4 9 14
1 4 10 14
2 1 11 21
2 1 12 21
2 1 13 21
2 1 14 21
2 2 15 22
2 2 16 22
2 2 17 22
2 3 18 23
2 3 19 23
2 4 20 24
Étape 1: filtrage par col1
SELECT * FROM StatsTest WHERE col1=1
Comme prévu, l'Optimiseur de requête devine le nombre exact de lignes.
Étape 2: filtrage par col2
SELECT * FROM StatsTest WHERE col2=1
Encore une fois, nous avons une estimation parfaite.
Étape 3: filtrage par col1 et col2
SELECT * FROM StatsTest WHERE col1=1 AND col2=1
Ici, l'estimation est loin d'être proche du nombre réel de lignes.
Le problème est que l'implicité de l'analyseur de requêtes suppose que col1 et col2 sont indépendantes mais ne le sont pas.
Étape 4: filtrage par col4
SELECT * FROM StatsTest WHERE col4 = 11
Je peux filtrer par col4 = 11 pour obtenir les mêmes résultats que la requête de l'étape 3, car col4 est une colonne calculée et selon la façon dont elle a été définie col1 = 1 et col2 = 1 est équivalent à col4 = 11 Ici, cependant, , comme prévu, l'estimation est parfaite.
Conclusion / Question
¿Cette solution artificielle et inélégante est-elle la seule option disponible pour obtenir des estimations précises lors du filtrage par deux colonnes ou plus non indépendantes? ¿La colonne calculée et le filtre par la colonne calculée sont-ils strictement nécessaires pour obtenir une précision réelle?
Exemple dans sqlfiddle