J'ai une table avec une colonne de chaînes et un prédicat qui vérifie les lignes d'une certaine longueur. Dans SQL Server 2014, je vois une estimation de 1 ligne quelle que soit la longueur que je vérifie. Cela donne des plans très médiocres car il y a en fait des milliers voire des millions de lignes et SQL Server choisit de placer cette table sur le côté externe d'une boucle imbriquée.
Existe-t-il une explication pour l'estimation de cardinalité de 1.0003 pour SQL Server 2014 alors que SQL Server 2012 estime 31.622 lignes? Existe-t-il une bonne solution de contournement?
Voici une courte reproduction du numéro:
-- Create a table with 1MM rows of dummy data
CREATE TABLE #customers (cust_nbr VARCHAR(10) NOT NULL)
GO
INSERT INTO #customers WITH (TABLOCK) (cust_nbr)
SELECT TOP 1000000
CONVERT(VARCHAR(10),
ROW_NUMBER() OVER (ORDER BY (SELECT NULL))) AS cust_nbr
FROM master..spt_values v1
CROSS JOIN master..spt_values v2
GO
-- Looking for string of a certain length.
-- While both CEs yield fairly poor estimates, the 2012 CE is much
-- more conservative (higher estimate) and therefore much more likely
-- to yield an okay plan rather than a drastically understimated loop join.
-- 2012: 31,622 rows estimated, 900K rows actual
-- 2014: 1 row estimated, 900K rows actual
SELECT COUNT(*)
FROM #customers
WHERE LEN(cust_nbr) = 6
OPTION (QUERYTRACEON 9481) -- Optionally, use 2012 CE
GO
Voici un script plus complet montrant des tests supplémentaires
J'ai également lu le livre blanc sur l'estimateur de cardinalité SQL Server 2014 , mais je n'y ai rien trouvé qui clarifie la situation.