SQL Server 2000“ NO JOIN PREDICATE”警告-なぜですか?
-
08-07-2019 - |
質問
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%)警告:参加しないでください
- 選択(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型ではないので、これは何の違いもありませんか、そうすべきですか? - この警告の存在は否定的な意味を持っていますか、それとも無視できますか?
- インデックスシークからインデックススキャンに切り替える理由
いくつかの背景情報:テーブルのカーディナリティは約です。 25,000レコードは1つのテーブルを記録します。他の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 を知っていますが、明らかにそうではありません。
解決
インデックスシークから切り替える理由 インデックススキャンの場合
これは主に推測ですが、ここに行きます:
最初のケース( 'Foo')では、MSSQLは検索対象の値がt1のインデックスの最初の部分と完全に一致することを認識するため、インデックスを使用してt1のレコードを検索します(インデックスシーク、おそらくバイナリ検索)。 t2に完全に一致するインデックスを持つレコードをt1で見つけたら、そのインデックスを使用してt2のレコードを見つけることができます。
2番目のケース(N'Foo ')では、MSSQLはインデックスとシークされている値が完全に一致していないことを認識するため、インデックスをインデックスとして使用できませんが、テーブル全体を実行する必要がありますスキャン。ただし、インデックスは必要な情報を(別の形式で)保持し、テーブル全体よりも小さいため、まるでテーブルであるかのようにインデックスのフルスキャンを実行できます(ページが少ないため、テーブルをスキャンするよりも高速です)ディスクを読み取る必要がありますが、インデックスシークの約90倍の時間がかかるようです)
他のヒント
クエリは、完全に形成された結合条件のように見える場合があります。ただし、クエリプランを調べると、関連する2つのテーブルに(結合されている場合)述語がないことを示す「結合述部なし」を示す警告が表示されます。クエリにオプション(強制順序)を追加すると、まったく異なる計画が作成され、警告が消えます(場合によっては)。これが、これが問題であることを知っている方法です。私が見たSQL 2000でパフォーマンスが向上したクエリのほとんどは、この問題を示しています。 SP 2への累積的な更新4は、問題を解決することになっています。