1

更新

我认为现在问这个还为时过早。又经过几次测试,我发现性能并没有提高。我将在这里执行更多测试并发布更新。到那时,不要费心回答这个问题。

我有一个这样的查询...

SELECT DISTINCT TOP 11 [Field_A] 
FROM   [#TempTable] 
WHERE  [Field_A] NOT IN (SELECT bo.[Id] 
                         FROM   [BusinessObject_Table] bo 
                         UNION 
                         SELECT boTemp.[Id] 
                         FROM   [#BusinessObject_Table] boTemp) 

这个查询需要永远运行一个相当大的数据集。我还在 Temp 表的 Id 列上添加了 CLUSTERED 索引,这带来了一些性能提升,但仍然未能完成。

我用这个替换了这个查询......

SELECT DISTINCT TOP 11 [Field_A] 
FROM   [#TempTable] 
WHERE  [Field_A] NOT IN (SELECT bo.[Id] 
                         FROM   [BusinessObject_Table] bo) 
       AND [Field_A] NOT IN (SELECT boTemp.[Id] 
                             FROM   [#BusinessObject_Table] boTemp) 

这在几秒钟内完成。有人可以解释这里发生了什么吗?

更新:我认为这两个查询是相同的。这就是我需要的。

BusinessObject_Table has following Ids: 1, 2, 3

#BusinessObject_Table has: 3, 4, 5

TempTable has rows whose Field_A values are: 1, 2, 3, 4, 6

查询的结果应该是:6(注意上面查询的变化)

我将尝试获取查询计划并将其发布在这里。

4

2 回答 2

3

猜测在没有查询计划的情况下......

子查询中的 UNION 强制使用 DISTINCT。使用单独的 IN 子句可以避免这种情况。但是,查询之间的逻辑不同(编辑:正如 Martin Smith 指出的那样)

使用 UNION ALL 和单个 IN 如果这是您想要的逻辑应该会更好

WHERE  [Field_A] NOT IN (SELECT bo.[Id] 
                     FROM   [BusinessObject_Table] bo 
                     UNION ALL
                     SELECT boTemp.[Id] 
                     FROM   [#BusinessObject_Table] boTemp)
于 2012-03-27T09:26:54.150 回答
2

我认为您应该以这种方式进行查询:

SELECT DISTINCT TOP 11 [Field_A] 
FROM   [#TempTable] 
WHERE NOT EXISTS(
  SELECT 1 FROM BusinessObject_Table bo WHERE #TempTable.FieldA = bo.Id
) AND NOT EXISTS(
  SELECT 1 FROM #BusinessObject_Table bo WHERE #TempTable.FieldA = bo.Id
) 

这样 SQL Server 可以使用它的优化器可能比您的 UNIONed 查询更好一些。优化器很可能会根据您的索引策略和表大小选择以不同的顺序运行您的查询。这很可能是最快的方法。虽然没有显示表结构和索引以及执行计划,但很难确定。

于 2012-03-27T11:12:13.227 回答