2008-11-14 54 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