Tengo una tabla con una columna de cadena y un predicado que busca filas con una cierta longitud. En SQL Server 2014, veo una estimación de 1 fila independientemente de la longitud que estoy buscando. Esto está generando planes muy pobres porque en realidad hay miles o incluso millones de filas y SQL Server está eligiendo colocar esta tabla en el lado externo de un bucle anidado.
¿Existe una explicación para la estimación de cardinalidad de 1,0003 para SQL Server 2014 mientras que SQL Server 2012 estima 31,622 filas? ¿Hay una buena solución?
Aquí hay una breve reproducción del problema:
-- 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
Aquí hay un script más completo que muestra pruebas adicionales
También leí el documento sobre el Estimador de cardinalidad de SQL Server 2014 , pero no encontré nada que aclarara la situación.