代码之家  ›  专栏  ›  技术社区  ›  Tomalak

SQL Server 2000“无连接谓词”警告-为什么?

  •  0
  • Tomalak  · 技术社区  · 17 年前

    有两个表,都有一个组合主键和一个聚集索引,两个键的结构相同:

    (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].[table2].[PK_table2](1%)
    • 嵌套循环(内部联接)(1%)
    • 选择(0%)

    这种行为让我有点困惑。

    • 为什么会有一个“无连接谓词”警告,为什么当我更改时它会消失 'Foo' N'Foo'
    • 此警告的存在是否具有负面影响,或者我是否可以忽略它?
    • 为什么它会从索引搜索切换到索引扫描?

    SQL_Latin1_General_CP1_CI_AS

    以下是本书的内容 @@VERSION :

    附言:我知道 KB322854 ,但显然不是这样。

    2 回复  |  直到 17 年前
        1
  •  2
  •   James Curran    17 年前

    为什么它会从索引搜索切换 到索引扫描?

    在第一种情况下('Foo'),MSSQL认识到正在搜索的值与t1上索引的第一部分完全匹配,因此使用索引在t1中查找记录(索引搜索,可能是二进制搜索)。在t1中找到一条索引与t2完全匹配的记录后,它可以使用该索引查找t2中的记录。

    在第二种情况下,(N'Foo'),MSSQL认识到它在索引和正在查找的值之间没有完美匹配,因此它不能将索引用作索引,但必须执行完整的表扫描。但是,由于索引包含所需的信息(以不同的形式),并且比完整的表小,因此它可以像扫描表一样对索引进行完整扫描(这比扫描表快,因为磁盘需要读取的页面更少;但是,它似乎比索引查找要长90倍)

        2
  •  0
  •   dkretz    17 年前

    From SqlServerCentral

    这些查询可以有一个看起来像完美格式的连接条件。但是,当您检查查询计划时,您将看到一条警告,指示“No Join Predicate”,指示所涉及的两个表没有谓词(在连接时)。向查询中添加一个选项(强制订单)将生成一个完全不同的计划,并且警告将消失(在某些情况下)。这就是你知道问题所在的原因。我看到的大多数在SQL 2000上性能更好的查询都显示了这个问题。SP 2的累积更新4应该可以解决此问题。