我能够在2008 R1 SP3 10.00.5512上进行复制,但是安装了最新的CU(14)可以修复该问题。
查看介于中间版本中的错误,看来您需要升级到包含以下修复的版本。
当您运行在SQL Server 2008或SQL Server 2012中的IN子句中包含许多常量值的查询时,访问冲突
在使用2008 R2时,您至少需要CU 9(用于SP1)或CU 5(用于SP2)。
症状的描述有些简短,但是提到了不匹配的数据类型
当您运行在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 Sever 2000错误也提到此临界点很重要。
用0到1047之间的值和100,000开始的直方图填充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
添加到in列表中后,该公式将不再起作用(估算的行,1902.75
而不是将生成的行1952
添加96
到总数中)。
BETWEEN
似乎使用了另一种计算基数估计的方法。
where mpnr BETWEEN 1 AND 20
估计只有1829.6行。我不知道如何从所示的直方图中得出。