추가 : SQL Server 2012는이 영역에서 일부 향상된 성능을 보여 주지만 아래에 언급 된 특정 문제를 해결하지 못하는 것 같습니다. 이것은
SQL Server 2012 이후 의 다음 주 버전에서 분명히 수정 되어야합니다 !
계획에 따르면 단일 삽입이 매개 변수화 된 프로 시저 (자동 매개 변수화 될 수 있음)를 사용하므로 이들에 대한 구문 분석 / 컴파일 시간이 최소화되어야합니다.
루프 ( script )를 설정하고 VALUES절의 수를 조정 하고 컴파일 시간을 기록 했지만이 부분을 좀 더 살펴 보겠다고 생각 했습니다.
그런 다음 컴파일 시간을 행 수로 나누어 절당 평균 컴파일 시간을 얻었습니다. 결과는 다음과 같습니다.

최대 250 개의 VALUES절이 컴파일 시간을 나타내며 절의 수는 약간의 상승 추세를 보이지만 너무 극적인 것은 아닙니다.

그러나 갑자기 변화가 있습니다.
해당 데이터 섹션이 아래에 나와 있습니다.
+------+----------------+-------------+---------------+---------------+
| Rows | CachedPlanSize | CompileTime | CompileMemory | Duration/Rows |
+------+----------------+-------------+---------------+---------------+
| 245 | 528 | 41 | 2400 | 0.167346939 |
| 246 | 528 | 40 | 2416 | 0.162601626 |
| 247 | 528 | 38 | 2416 | 0.153846154 |
| 248 | 528 | 39 | 2432 | 0.157258065 |
| 249 | 528 | 39 | 2432 | 0.156626506 |
| 250 | 528 | 40 | 2448 | 0.16 |
| 251 | 400 | 273 | 3488 | 1.087649402 |
| 252 | 400 | 274 | 3496 | 1.087301587 |
| 253 | 400 | 282 | 3520 | 1.114624506 |
| 254 | 408 | 279 | 3544 | 1.098425197 |
| 255 | 408 | 290 | 3552 | 1.137254902 |
+------+----------------+-------------+---------------+---------------+
선형 적으로 증가하던 캐시 된 계획 크기는 갑자기 떨어지지 만 CompileTime은 7 배 증가하고 CompileMemory는 증가합니다. 이것은 자동 매개 변수화 된 계획 (1,000 개의 매개 변수 포함)에서 매개 변수화되지 않은 계획 사이의 컷오프 지점입니다. 그 후에는 (주어진 시간에 처리되는 값 절의 수 측면에서) 선형 적으로 덜 효율적으로 보입니다.
왜 그래야하는지 잘 모르겠습니다. 아마도 특정 리터럴 값에 대한 계획을 컴파일 할 때 선형 적으로 확장되지 않는 일부 활동 (예 : 정렬)을 수행해야합니다.
중복 행으로 만 구성된 쿼리를 시도했을 때 캐시 된 쿼리 계획의 크기에 영향을 미치지 않는 것 같고, 상수 테이블의 출력 순서에도 영향을주지 않습니다 (그리고 정렬에 소요되는 힙 시간에 삽입 할 때) 어쨌든 무의미 할 것입니다).
또한 클러스터형 인덱스가 테이블에 추가되면 계획은 여전히 명시적인 정렬 단계를 표시하므로 런타임에 정렬을 피하기 위해 컴파일 타임에 정렬되지 않는 것 같습니다.

디버거에서 이것을 보려고했지만 내 SQL Server 2008 버전에 대한 공용 기호를 사용할 수없는 것 같아서 대신 UNION ALLSQL Server 2005에서 동일한 구성 을 살펴 봐야했습니다 .
일반적인 스택 추적은 다음과 같습니다.
sqlservr.exe!FastDBCSToUnicode() + 0xac bytes
sqlservr.exe!nls_sqlhilo() + 0x35 bytes
sqlservr.exe!CXVariant::CmpCompareStr() + 0x2b bytes
sqlservr.exe!CXVariantPerformCompare<167,167>::Compare() + 0x18 bytes
sqlservr.exe!CXVariant::CmpCompare() + 0x11f67d bytes
sqlservr.exe!CConstraintItvl::PcnstrItvlUnion() + 0xe2 bytes
sqlservr.exe!CConstraintProp::PcnstrUnion() + 0x35e bytes
sqlservr.exe!CLogOp_BaseSetOp::PcnstrDerive() + 0x11a bytes
sqlservr.exe!CLogOpArg::PcnstrDeriveHandler() + 0x18f bytes
sqlservr.exe!CLogOpArg::DeriveGroupProperties() + 0xa9 bytes
sqlservr.exe!COpArg::DeriveNormalizedGroupProperties() + 0x40 bytes
sqlservr.exe!COptExpr::DeriveGroupProperties() + 0x18a bytes
sqlservr.exe!COptExpr::DeriveGroupProperties() + 0x146 bytes
sqlservr.exe!COptExpr::DeriveGroupProperties() + 0x146 bytes
sqlservr.exe!COptExpr::DeriveGroupProperties() + 0x146 bytes
sqlservr.exe!CQuery::PqoBuild() + 0x3cb bytes
sqlservr.exe!CStmtQuery::InitQuery() + 0x167 bytes
sqlservr.exe!CStmtDML::InitNormal() + 0xf0 bytes
sqlservr.exe!CStmtDML::Init() + 0x1b bytes
sqlservr.exe!CCompPlan::FCompileStep() + 0x176 bytes
sqlservr.exe!CSQLSource::FCompile() + 0x741 bytes
sqlservr.exe!CSQLSource::FCompWrapper() + 0x922be bytes
sqlservr.exe!CSQLSource::Transform() + 0x120431 bytes
sqlservr.exe!CSQLSource::Compile() + 0x2ff bytes
따라서 스택 추적에서 이름을 제거하면 문자열을 비교하는 데 많은 시간이 소요되는 것으로 보입니다.
이 KB 문서 는 쿼리 처리 DeriveNormalizedGroupProperties의 정규화 단계 라고 불렸던 것과 관련이 있음을 나타냅니다.
이 단계는 이제 binding 또는 algebrizing이라고하며 이전 구문 분석 단계의 표현식 구문 분석 트리 출력을 가져와 최적화 (이 경우 사소한 계획 최적화) [ref] 로 진행하기 위해 알고리즘 화 된 표현식 트리 (쿼리 프로세서 트리)를 출력합니다 .
원래 테스트를 다시 실행하는 실험 ( Script )을 하나 더 시도했지만 세 가지 사례를 살펴 보았습니다 .
- 중복이없는 길이 10 자의 이름 및 성 문자열입니다.
- 중복이없는 50 자 길이의 이름 및 성 문자열.
- 이름 및 성 길이가 모두 중복 된 10 자 문자열입니다.

문자열이 길수록 더 나쁜 결과를 얻고 반대로 중복이 많을수록 더 좋은 결과를 얻는다는 것을 분명히 알 수 있습니다. 앞서 언급했듯이 중복은 캐시 된 계획 크기에 영향을주지 않으므로 algebrized 표현 트리 자체를 구성 할 때 중복 식별 프로세스가 있어야한다고 가정합니다.
편집하다
이 정보가 활용되는 한 곳은 여기 @Lieven 이 보여줍니다.
SELECT *
FROM (VALUES ('Lieven1', 1),
('Lieven2', 2),
('Lieven3', 3))Test (name, ID)
ORDER BY name, 1/ (ID - ID)
컴파일 타임에 Name열에 중복이 없음을 확인할 수 있기 때문에 1/ (ID - ID)런타임에 보조 식에 의한 정렬을 건너 뛰고 (계획의 정렬에는 ORDER BY열 이 하나만 있음 ) 0으로 나누기 오류가 발생하지 않습니다. 중복 항목이 테이블에 추가되면 정렬 연산자는 열별로 두 순서를 표시하고 예상 오류가 발생합니다.