SQL 查询 UNION 性能
Posted
技术标签:
【中文标题】SQL 查询 UNION 性能【英文标题】:SQL Query UNION Performance 【发布时间】:2012-03-27 09:15:08 【问题描述】:更新
我认为现在问这个还为时过早。又经过几次测试,我发现性能并没有提高。我将在这里执行更多测试并发布更新。到那时,不要费心回答这个问题。
我有一个这样的查询...
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(注意上面查询的变化)
我会尝试获取查询计划并在此处发布。
【问题讨论】:
请发布计划。无论如何,查询会做不同的事情。第二个检查它是否没有出现在两个表中。第一个表。第一个需要使用intersect
或第二个or
才能相同。
【参考方案1】:
在没有查询计划的情况下猜测...
子查询中的 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)
【讨论】:
【参考方案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 查询好一点。优化器很可能会根据您的索引策略和表大小选择以不同的顺序运行您的查询。这很可能是最快的方法。虽然没有显示表结构和索引以及执行计划,但很难确定。
【讨论】:
谢谢。现在查询速度很快。我将对此进行测试,稍后在此处发布更多 cmets(以及执行计划)以上是关于SQL 查询 UNION 性能的主要内容,如果未能解决你的问题,请参考以下文章