【问题标题】:SQL EXCEPT performanceSQL 除了性能
【发布时间】:2013-04-11 15:36:33
【问题描述】:

我正在尝试使用类似于以下查询的查询来查找两个表之间的差异(DEV 数据库与 TEST 数据库中的同一个表)。每个表有约 30K 行和约 5 列。

select field1,field2,field3,field4,field5 from dev.dbo.table1 
where field1+field2 in ('string1','string2','string3',...,'string50')
except
select field1,field2,field3,field4,field5 from test.dbo.table1 
where field1+field2 in ('string1','string2','string3',...,'string50')

field1 是char(5),field2 是char(1)

这个查询基本上永远不会终止。

当我使用SET SHOWPLAN_ALL ON 分析这个查询时,我可以看到树中有一个非常高的嵌套循环。当我将上述查询更改为

select * from dev.dbo.table1 
except
select * from test.dbo.table2

查询运行很快,执行计划中没有嵌套循环。

有人可以帮忙解释一下吗?我不明白为什么会有很大的不同。

【问题讨论】:

  • Microsoft SQL Server 2005

标签: sql sql-server-2005 except


【解决方案1】:

我的最佳猜测是优化器在估计两个表的基数(大小)方面做得很差。因为它低估了大小,所以生成的查询计划很差。

在 SQL Server 中,您可以在 except 上使用 join 提示。所以,你可以得到你想要的查询:

select field1,field2,field3,field4,field5 from dev.dbo.table1 
where field1+field2 in ('string1','string2','string3',...,'string50')
except
select field1,field2,field3,field4,field5 from test.dbo.table1 
where field1+field2 in ('string1','string2','string3',...,'string50')
option (hash join, merge join)

这消除了嵌套循环连接的选项,选择了更有利的方法。

【讨论】:

  • 我已经确认确实如此。对其他数据库执行相同的查询时不会出现嵌套循环,因此故障似乎出在 SQL Server 上。
【解决方案2】:

您的第一个查询很慢,因为您在 where 子句中连接字段,这本质上是一个函数。在 where 子句中运行函数时,几乎都会发生这种情况。这是一个更简单的例子。这会很快。

where myDateTimeField >= @DateValue
and myDateTimeField < dateadd(day, 1, @DateValue)

这在逻辑上是一样的,但是会很慢

where cast(myDateTimeField as date) = @DateValue

【讨论】:

  • 谢谢,我在两个数据库的临时表中都选择了 table1,并添加了 field1+field2 列,将查询更改为使用临时表,这也解决了我的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-24
  • 1970-01-01
相关资源
最近更新 更多