SQL Server 2000“ NO JOIN PREDICATE”警告-为什么?
-
08-07-2019 - |
题
SQL Server 2000出现了一个奇怪的问题,我只是想不出发生这种情况的原因。
有两个表,两个表都有组合的主键,上面带有聚集索引,两个键的结构相同: 通用标签
所以,像这样加入他们很容易: 通用标签
看看查询执行计划,我看到了:
- 聚集索引寻求[db]。[dbo]。[table1]。[PK_table1](48%)
- 聚集索引寻求[db]。[dbo]。[table2]。[PK_table2](51%)
- 嵌套循环(内部联接)(1%)警告:没有联接预测
- 选择(0%)
现在,如果我这样做(请注意NVARCHAR字符串!): 通用标签
我得到:
- 集群索引扫描[db]。[dbo]。[table1]。[PK_table1](98%)
- 聚集索引寻求[db]。[dbo]。[table2]。[PK_table2](1%)
- 嵌套循环(内部加入)(1%)此处无警告
- 选择(0%)
这种行为让我有些困惑。
- 为什么会有“ NO JOIN PREDICATE”警告,为什么当我将
'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(Intel X86)2008年3月7日版权所有(c)1988-2003 Windows NT 5.0上的Microsoft Corporation Enterprise Edition(Build 2195:Service Pack 4)
PS:我知道 KB322854 ,但是显然不是。 / p>
- 为什么会有“ NO JOIN PREDICATE”警告,为什么当我将
解决方案
为什么从索引搜索中切换 进行索引扫描?
这在很大程度上是一种猜测,但是在这里:
在第一种情况下('Foo'),MSSQL会识别出要搜索的值与t1索引的第一部分完全匹配,因此使用索引在t1中查找记录(索引查找,可能是二进制搜索)。在t1中找到一条记录,该记录的索引与t2完全匹配后,便可以使用该索引在t2中查找记录。
在第二种情况下(N'Foo'),MSSQL认识到索引与所寻找的值之间没有完美的匹配,因此它不能将索引用作索引,但必须执行完整的表扫描。但是,由于索引保存了所需的信息(采用不同的形式)并且小于完整表,因此它可以像对表一样对索引进行完整扫描(这比扫描表要快,因为页面较少需要为磁盘读取;但是,它似乎比索引查找花费了大约90倍的时间)
其他提示
查询可以具有看起来很完美的联接条件。但是,当您检查查询计划时,将看到一个警告,指示“无联接谓词”,指示所涉及的两个表没有谓词(联接时)。向查询添加选项(强制定单)会产生完全不同的计划,并且警告会消失(在某些情况下)。这样您才能知道这是问题所在。我所见过的大多数查询在SQL 2000上的性能都更好,它们都存在此问题。SP 2的累积更新4应该可以解决此问题。