SUBSTRING () 또는 다른 문자열 함수를 포함하는 술어의 카디널리티 추정 방법에 대한 SQL Server 2016의 변경 사항에 대한 문서 나 연구가 있습니까?
내가 묻는 이유는 호환성 모드 130에서 성능이 저하 된 쿼리를보고 있었고 그 이유는 SUBSTRING ()에 대한 호출이 포함 된 WHERE 절과 일치하는 행 수의 추정치 변경과 관련이 있기 때문입니다. 쿼리 다시 쓰기 문제를 해결했지만 SQL Server 2016에서이 영역의 변경 사항에 대한 설명서를 알고있는 사람이 있는지 궁금합니다.
데모 코드는 다음과 같습니다. 이 테스트 사례에서는 추정치가 매우 비슷하지만 정확도는 데이터에 따라 다릅니다.
테스트 사례에서, compat 레벨 120에서 SQL Server는 추정에 히스토그램을 사용하는 것으로 보이지만 compat 레벨 130에서 SQL Server는 테이블 일치의 고정 된 10 %를 가정하는 것으로 보입니다.
CREATE DATABASE MyStringTestDB;
GO
USE MyStringTestDB;
GO
DROP TABLE IF EXISTS dbo.StringTest;
CREATE TABLE dbo.StringTest ( [TheString] varchar(15) );
GO
INSERT INTO dbo.StringTest
VALUES
( 'Y5_CLV' );
INSERT INTO dbo.StringTest
VALUES
( 'Y5_EG3' );
INSERT INTO dbo.StringTest
VALUES
( 'ZY_NE' );
INSERT INTO dbo.StringTest
VALUES
( 'ZY_PQT' );
INSERT INTO dbo.StringTest
VALUES
( 'ZY_T2V' );
INSERT INTO dbo.StringTest
VALUES
( 'ZY_TT4' );
INSERT INTO dbo.StringTest
VALUES
( 'ZY_ZKK' );
INSERT INTO dbo.StringTest
VALUES
( 'ZZ_LW6' );
INSERT INTO dbo.StringTest
VALUES
( 'ZZ_QO3' );
INSERT INTO dbo.StringTest
VALUES
( 'ZZ_TZ7' );
INSERT INTO dbo.StringTest
VALUES
( 'ZZ_UZZ' );
CREATE CLUSTERED INDEX IX_Clustered ON dbo.StringTest (TheString);
/*
Uses fixed % for estimate; 1.1 rows estimated in this case.
Plan for computation:
CSelCalcFixedFilter (0.1) <----
Selectivity: 0.1
*/
ALTER DATABASE MyStringTestDB SET compatibility_level = 130;
GO
SELECT *
FROM dbo.StringTest
WHERE SUBSTRING(TheString, 1, CHARINDEX('_',TheString) - 1) = 'ZZ'
OPTION (QUERYTRACEON 2363, QUERYTRACEON 3604);
/*
Uses histogram to get estimate of 1
CSelCalcPointPredsFreqBased <----
Distinct value calculation:
CDVCPlanLeaf
0 Multi-Column Stats, 1 Single-Column Stats, 0 Guesses
Individual selectivity calculations:
(none)
Loaded histogram for column QCOL: [DBA].[dbo].[StringTest].TheString from stats with id 1
*/
ALTER DATABASE MyStringTestDB SET compatibility_level = 120;
GO
SELECT *
FROM dbo.StringTest
WHERE SUBSTRING(TheString, 1, CHARINDEX('_',TheString) - 1) = 'ZZ'
OPTION (QUERYTRACEON 2363, QUERYTRACEON 3604);
/*
-- Simpler rewrite; works fine in both compat levels and gets better estimate.
SELECT *
FROM dbo.StringTest
WHERE TheString LIKE 'ZZ[_]%'
OPTION (QUERYTRACEON 2363, QUERYTRACEON 3604);
*/
Y5_EG3
문자열이 코드이고 항상 대문자이면 이진 데이터 정렬을 항상 시도하면Latin1_General_100_BIN2
필터링 작업 속도가 향상됩니다. 그냥 추가COLLATE Latin1_General_100_BIN2
받는 사람CREATE TABLE
바로 후, 문varchar(15)
. 계획 생성 / 추정에 영향을 미치는지 궁금합니다.