转换为数字后,奇怪的SQL Server实例崩溃


20

使用C#实体框架时,我注意到我的SQL Server实例崩溃了。

我能够将其追溯到以下语句:

SELECT * FROM dbo.[TestTable]
where mpnr in (1099059904,
1038139906,
1048119902,
1045119902,
1002109903,
1117109910,
1111149902,
1063149902,
1117159902,
1116109904,
1105079905,
1012079906,
1129129904,
1103059905,
1065059905,
1091059906,
1110149904,
1129149903,
1083029905,
1080139904,
1076109903,
1010019902,
1058019902,
1060019903,
1053019902,
1030089902,
1018149902,
1077149902,
1010109901,
1011109901,
1000119902,
1023049903,
1107119909,
1108119909,
1106119909)

该表如下所示:

CREATE TABLE dbo.[TestTable]([MPNR] [numeric](9, 0) NOT NULL)

每当我启动查询时都会发生当机。如果我减少该IN子句中的值数量,它会起作用。(当然,它不返回任何行。)

我知道该IN子句中的值是10位数字,并且该列只有9位数字,但是这不会导致整个SQL Server实例崩溃。

我的SQL Server版本是Windows Server 2003 32位上的2008 R2。

这是一个已知的错误?是否有SQL Server修补程序?


评论不作进一步讨论;此对话已转移至聊天
保罗·怀特说GoFundMonica

Answers:


20

我能够在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行。我不知道如何从所示的直方图中得出。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.