문자열 열이있는 테이블과 특정 길이의 행을 검사하는 술어가 있습니다. SQL Server 2014에서 확인하는 길이에 관계없이 예상 1 행이 표시됩니다. 실제로 수천 또는 수백만 개의 행이 있고 SQL Server가이 테이블을 중첩 루프의 외부에 배치하도록 선택하기 때문에 계획이 매우 좋지 않습니다.
SQL Server 2014의 카디널리티 예상 1.0003에 대한 설명이있는 반면 SQL Server 2012는 31,622 개의 행을 추정합니까? 좋은 해결 방법이 있습니까?
다음은이 문제를 간단히 재현 한 것입니다.
-- 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 Cardinality Estimator에 대한 백서를 읽었 지만 상황을 명확히하는 내용을 찾지 못했습니다.