2008-11-14 51 views
0

我在SQL Server 2000中遇到了一個奇怪的問題,我無法想到發生這種情況的原因。SQL Server 2000「無連接預測」警告 - 爲什麼?

有兩個表,都具有在其上的聚集的索引的組合的主鍵,這兩個鍵具有相同的結構:

(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] [表1] [PK_table1。 ](48%)
  • 羣集索引查找[分貝] [DBO] [表2] [PK_table2](51%)
  • 嵌套循環(內加入)(1%)警告:。NO聯接謂詞
  • 選擇(0%)

現在,如果我這樣做(注意NVARCHAR字符串!):

SELECT t1.Foo, t2.Bar 
FROM table1 t1 INNER JOIN table2 t2 ON t1.VarcharKey = t2.VarcharKey 
WHERE t1.VarcharKey = N'Foo' 

我得到:

  • Clustered Index Scan [db]。[dbo]。[table1]。[PK_table1](98%)
  • Clustered Index Seek [db]。[dbo]。[table2]。[PK_table2](1%)
  • 嵌套循環(內部連接)(1%)沒有警告這裏
  • 選擇(0%)

這種行爲讓我有點摸不着頭腦。

  • 爲什麼會出現「NO連接謂詞」的警告,爲什麼會消失,當我改變'Foo'N'Foo'?我的鍵列不是NVARCHAR類型的,所以這不應該有什麼區別,或者它應該如何?
  • 此警告的存在是否有負面影響,或者我可以忽略它嗎?
  • 爲什麼它從索引搜索切換到索引掃描?

一些背景信息:表基數爲約25,000記錄一張桌子,約。另一個是12,000個記錄。數據庫兼容級別爲80(SQL Server 2000)默認排序規則爲SQL_Latin1_General_CP1_CI_AS,如果這樣做有任何區別的話。

這裏是@@VERSION內容:

的Microsoft SQL Server 2000 - 8.00.2273(英特爾X86)2008年3月7日22時19分58秒版權所有(C)1988-2003微軟公司企業版在Windows NT上5.0(Build 2195:Service Pack 4)

PS:我知道KB322854,但顯然這不是。

回答

2

爲什麼它從索引搜索 切換到索引掃描?

這在很大程度上是一種猜測,但在這裏有雲:

在第一種情況下(「富」),MSSQL認識到值爲搜索是對指數的第一部分是絕配t1,因此使用該索引在t1中查找記錄(索引搜索,可能是二進制搜索)。在t1中找到一個與t2完美匹配的索引的記錄後,它可以使用索引在t2中查找記錄。

在第二種情況下(N'Foo'),MSSQL認識到它沒有索引和查找值之間的完美匹配,所以它不能使用該索引作爲索引,但必須完成表掃描。但是,由於索引保存了所需的信息(以不同的形式)並且小於整個表格,因此它可以對索引進行全面掃描,就好像它是表格一樣(這比掃描表格要快,因爲更少的頁面需要讀取磁盤;不過,它似乎需要比索引查找長約90倍)

+0

我遇到了與SQL Server 2000相同的問題:當您嘗試在已索引的非Unicode列中搜索unicode字符串時,SQL Server 2000無法將前者轉換爲後者。因此它確實索引掃描而不是索引查找。 FWIW:在這種情況下,SQL Server 2005更智能。 – Yarik 2008-11-15 09:37:22

0

From SqlServerCentral

查詢能有什麼看起來像一個五臟俱全的連接條件。但是,當您檢查查詢計劃時,您將看到一條警告,指示「無連接謂詞」,表示涉及的兩個表沒有謂詞(連接時)。向查詢添加選項(強制順序)會產生完全不同的計劃,並且警告消失(在某些情況下)。這就是你如何知道這是問題所在。大部分我看到的在SQL 2000上執行得更好的查詢都表現出這個問題。 SP 2的累積更新4應該可以解決問題。

+0

我知道這一點的信息(我在PS中這麼說)。實際上SQL服務器已經應用了SP4。 – Tomalak 2008-11-16 14:13:37