Ich habe eine Tabelle mit einer Zeichenfolgenspalte und einem Prädikat, das nach Zeilen mit einer bestimmten Länge sucht. In SQL Server 2014 wird unabhängig von der Länge, auf die ich prüfe, eine Schätzung von 1 Zeile angezeigt. Dies führt zu sehr schlechten Plänen, da tatsächlich Tausende oder sogar Millionen von Zeilen vorhanden sind und SQL Server diese Tabelle auf der Außenseite einer verschachtelten Schleife ablegt.
Gibt es eine Erklärung für die Kardinalitätsschätzung von 1.0003 für SQL Server 2014, während SQL Server 2012 31.622 Zeilen schätzt? Gibt es eine gute Problemumgehung?
Hier ist eine kurze Reproduktion des Problems:
-- 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
Hier ist ein vollständigeres Skript, das zusätzliche Tests zeigt
Ich habe auch das Whitepaper zum SQL Server 2014 Cardinality Estimator gelesen , aber dort nichts gefunden, was die Situation verdeutlicht.