SQL Server 2000 で奇妙な問題が発生しましたが、これが発生する理由が思いつきません。
2 つのテーブルがあり、どちらも主キーとクラスター化インデックスが組み合わされており、両方のキーの構造は同じです。
(VARCHAR(11), INT, DATETIME) /* can't change this, so don't suggest I should */
したがって、このように参加するのは簡単です。
SELECT t1.Foo, t2.Bar
FROM table1 t1 INNER JOIN table2 t2 ON t1.VarcharKey = t2.VarcharKey
WHERE t1.VarcharKey = 'Foo'
クエリ実行プランを見ると、次のようになります。
- クラスタ化インデックス シーク [db].[dbo].[table1].[PK_table1] (48%)
- クラスタ化インデックス シーク [db].[dbo].[table2].[PK_table2] (51%)
- ネストされたループ (内部結合) (1%)警告: NO JOIN PREDICATE
- 選択 (0%)
これを行うと(NVARCHAR文字列に注意してください!):
SELECT t1.Foo, t2.Bar
FROM table1 t1 INNER JOIN table2 t2 ON t1.VarcharKey = t2.VarcharKey
WHERE t1.VarcharKey = N'Foo'
私は得る:
- クラスター化インデックス スキャン [db].[dbo].[table1].[PK_table1] (98%)
- クラスタ化インデックス シーク [db].[dbo].[table2].[PK_table2] (1%)
- ネストされたループ (内部結合) (1%)ここでは警告なし
- 選択 (0%)
この振る舞いは、私を少し困惑させます。
- 「NO JOIN PREDICATE」という警告が表示されるのはなぜですか? に変更
'Foo'
すると警告が消えるのはなぜN'Foo'
ですか? 私のキー列は NVARCHAR 型ではないので、違いはありませんか? - この警告の存在は否定的な意味を持ちますか、それとも無視できますか?
- インデックス シークからインデックス スキャンに切り替わるのはなぜですか?
いくつかの背景情報: テーブルのカーディナリティは約です。1 つのテーブルに 25,000 レコード。他に12,000件のレコード。データベースの互換性レベルは 80 (SQL Server 2000) です。デフォルトの照合順序はSQL_Latin1_General_CP1_CI_AS
、違いがある場合は です。
の内容は次の@@VERSION
とおりです。
Microsoft SQL Server 2000 - 8.00.2273 (Intel X86) 2008 年 3 月 7 日 22:19:58 Copyright (c) 1988-2003 Microsoft Corporation Enterprise Edition on Windows NT 5.0 (Build 2195: Service Pack 4)
PS: KB322854は知っていますが、これは明らかにそうではありません。