Pour un COUNT(DISTINCT)
qui a ~ 1 milliard de valeurs distinctes, je reçois un plan de requête avec un agrégat de hachage estimé à seulement ~ 3 millions de lignes.
Pourquoi cela arrive-t-il? SQL Server 2012 produit une bonne estimation, est-ce donc un bogue dans SQL Server 2014 que je dois signaler sur Connect?
La requête et la mauvaise estimation
-- Actual rows: 1,011,719,166
-- SQL 2012 estimated rows: 1,079,130,000 (106% of actual)
-- SQL 2014 estimated rows: 2,980,240 (0.29% of actual)
SELECT COUNT(DISTINCT factCol5)
FROM BigFactTable
OPTION (RECOMPILE, QUERYTRACEON 9481) -- Include this line to use SQL 2012 CE
-- Stats for the factCol5 column show that there are ~1 billion distinct values
-- This is a good estimate, and it appears to be what the SQL 2012 CE uses
DBCC SHOW_STATISTICS (BigFactTable, _WA_Sys_00000005_24927208)
--All density Average Length Columns
--9.266754E-10 8 factCol5
SELECT 1 / 9.266754E-10
-- 1079126520.46229
Le plan de requête
Script complet
Ce que j'ai essayé jusqu'à présent
J'ai fouillé dans les statistiques de la colonne pertinente et constaté que le vecteur de densité montre environ 1,1 milliard de valeurs distinctes. SQL Server 2012 utilise cette estimation et produit un bon plan. Étonnamment, SQL Server 2014 semble ignorer l'estimation très précise fournie par les statistiques et utilise à la place une estimation beaucoup plus faible. Cela produit un plan beaucoup plus lent qui ne réserve pas assez de mémoire et se répand à tempdb.
J'ai essayé le drapeau de trace 4199
, mais cela n'a pas réglé la situation. Enfin, j'ai essayé de creuser pour optimiser les informations via une combinaison d'indicateurs de trace (3604, 8606, 8607, 8608, 8612)
, comme démontré dans la seconde moitié de cet article . Cependant, je n'ai pu voir aucune information expliquant la mauvaise estimation jusqu'à ce qu'elle apparaisse dans l'arborescence de sortie finale.
Problème de connexion
Sur la base des réponses à cette question, j'ai également classé ce problème dans Connect
la source