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以上」を意味するのではないかと疑っています。これは、カーディナリティを推定する2つの異なる方法のカットオフポイントであるためです。
クラッシュはCScaOp_In::FCalcSelectivity()
、LoadHistogramFromXVariantArray()
やなどの名前で呼び出されるいくつかのメソッド内で発生していましたCInMemHistogram::FJoin() -> WalkHistograms()
。
リスト項目の19以下の個別の場合、これらのメソッドはまったく呼び出されませんでした。同様のSQL Severを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行のみを推定します。表示されたヒストグラムからそれがどのように導出されるのかわかりません。