0

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は知っていますが、これは明らかにそうではありません。

4

2 に答える 2

2

インデックス シークからインデックス スキャンに切り替わるのはなぜですか?

これは主に推測ですが、次のようになります。

最初のケース ('Foo') では、MSSQL は検索対象の値が t1 のインデックスの最初の部分に完全に一致することを認識し、インデックスを使用して t1 のレコードを検索します (インデックス シーク、場合によってはバイナリ探す)。t2 と完全に一致するインデックスを持つレコードが t1 で見つかったので、そのインデックスを使用して t2 でレコードを検索できます。

2 番目のケース (N'Foo') では、MSSQL は、インデックスとシークされている値が完全に一致していないことを認識するため、インデックスをインデックスとして使用できず、完全なテーブル スキャンを実行する必要があります。ただし、インデックスは必要な情報を (別の形式で) 保持しており、完全なテーブルよりも小さいため、テーブルであるかのようにインデックスのフル スキャンを実行できます (ページ数が少ないため、テーブルをスキャンするよりも高速です)。ディスクの読み取りが必要ですが、インデックスのシークよりも約 90 倍の時間がかかるようです)

于 2008-11-14T18:31:13.373 に答える
0

SqlServerCentral から:

クエリには、完全に形成された結合条件のように見えるものを含めることができます。ただし、クエリ プランを調べると、関連する 2 つのテーブルに述語がないことを示す「結合述語なし」という警告が表示されます (結合された場合)。オプション (Force Order) をクエリに追加すると、まったく異なる計画が生成され、警告が表示されなくなります (場合によっては)。これが問題であることを知る方法です。SQL 2000 でパフォーマンスが向上したクエリのほとんどで、この問題が発生しています。SP 2 への累積的な更新プログラム 4 は、問題を解決するはずです。

于 2008-11-14T18:18:14.630 に答える