У меня есть таблица со строковым столбцом и предикатом, который проверяет строки определенной длины. В SQL Server 2014 я вижу оценку в 1 строку независимо от длины, которую я проверяю. Это приводит к очень плохим планам, потому что на самом деле есть тысячи или даже миллионы строк, и SQL Server предпочитает размещать эту таблицу на внешней стороне вложенного цикла.
Есть ли объяснение для оценки мощности 1.0003 для SQL Server 2014, а для SQL Server 2012 - 31622 строки? Есть ли хороший обходной путь?
Вот краткое воспроизведение вопроса:
-- 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
Вот более полный скрипт, показывающий дополнительные тесты
Я также прочитал технический документ по оценщику мощности SQL Server 2014 , но не нашел там ничего, что прояснило бы ситуацию.