2008 R1 SP3 10.00.5512에서 재현 할 수 있었지만 최신 CU (14)를 설치하면 문제가 해결되었습니다.
중간 버전에서 수정 된 버그를 검토하면 다음 수정 사항이 포함 된 빌드로 업그레이드해야하는 것처럼 보입니다.
SQL Server 2008 또는 SQL Server 2012의 IN 절에 많은 상수 값이 포함 된 쿼리를 실행할 때 액세스 위반
2008 R2를 사용하는 경우 SP1의 경우 CU 9 이상, SP2의 경우 CU 5 이상이 필요합니다.
증상에 대한 설명이 다소 간단하지만 일치하지 않는 데이터 유형이 언급 됨
Microsoft SQL Server 2008, Microsoft SQL Server 2012 또는 Microsoft SQL Server 2008 R2의 IN 절에 많은 상수 값이 포함 된 쿼리를 실행하면 액세스 위반이 발생할 수 있습니다.
참고 문제가 발생하기 위해 IN 절의 상수는 열 데이터 형식과 정확히 일치 할 수 없습니다.
"많은"을 정의하지 않습니다. 테스트에서 나는 이것이 카디널리티를 추정하는 두 가지 다른 방법 사이의 컷오프 포인트 인 것처럼 보이기 때문에 이것이 "20 이상"을 의미한다고 생각합니다.
충돌이 호출 방법 중 몇 가지 내부에 무슨 일이 일어 CScaOp_In::FCalcSelectivity()
등의 이름으로 LoadHistogramFromXVariantArray()
와 CInMemHistogram::FJoin() -> WalkHistograms()
.
목록 항목이 19 개 이하인 경우이 메서드는 전혀 호출되지 않았습니다. 유사한 SQL 끊다 2000 버그는 상당한로 포인트 떨어져,이 컷을 언급하고있다.
0에서 1047 사이의 값을 가진 100,000 개의 행으로 구성된 임의의 테스트 데이터와 다음과 같이 시작하는 히스토그램으로 테스트 테이블 채우기
+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 0 | 0 | 104 | 0 | 1 |
| 8 | 672 | 118 | 7 | 96 |
| 13 | 350 | 118 | 4 | 87.5 |
| 18 | 395 | 107 | 4 | 98.75 |
| 23 | 384 | 86 | 4 | 96 |
| 28 | 371 | 85 | 4 | 92.75 |
+--------------+------------+---------+---------------------+----------------+
쿼리
SELECT * FROM dbo.[TestTable]
where mpnr in (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19)
option (maxdop 1)
1856 년 예상 행을 표시합니다.
이것은 19 개의 등식 술어에 대한 예상 행을 개별적으로 가져와 함께 더하면 예상됩니다.
+-------+----------------+-------+
| 1-7 | AVG_RANGE_ROWS | 96 |
| 8 | EQ_ROWS | 118 |
| 9-12 | AVG_RANGE_ROWS | 87.5 |
| 13 | EQ_ROWS | 118 |
| 14-17 | AVG_RANGE_ROWS | 98.75 |
| 18 | EQ_ROWS | 107 |
| 19 | AVG_RANGE_ROWS | 96 |
+-------+----------------+-------+
7*96 + 118 + 4*87.5 + 118 + 4*98.75 + 107 + 1*96 = 1856
공식이 더 이상 20
목록에 추가 된 후에 는 공식이 작동하지 않습니다 ( 총계에 다른 것을 추가하는 1902.75
것이 아니라 예상 행 ).1952
96
BETWEEN
카디널리티 추정값을 계산하는 또 다른 방법을 사용하는 것 같습니다.
where mpnr BETWEEN 1 AND 20
1829.6 개의 행만 추정합니다. 나는 이것이 표시된 히스토그램에서 어떻게 파생되는지 전혀 모른다.