Ho una tabella con una colonna stringa e un predicato che controlla le righe con una certa lunghezza. In SQL Server 2014, vedo una stima di 1 riga indipendentemente dalla lunghezza che sto verificando. Ciò sta producendo piani molto scadenti perché in realtà ci sono migliaia o addirittura milioni di righe e SQL Server sta scegliendo di posizionare questa tabella sul lato esterno di un ciclo nidificato.
Esiste una spiegazione per la stima della cardinalità di 1.0003 per SQL Server 2014 mentre SQL Server 2012 stima 31.622 righe? C'è una buona soluzione?
Ecco una breve riproduzione 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
Ecco uno script più completo che mostra ulteriori test
Ho anche letto il white paper sullo stimatore di cardinalità di SQL Server 2014 , ma non ho trovato nulla che chiarisse la situazione.