2013-04-18 38 views
2

我正在嘗試使用類似於以下查詢的查詢來查找兩個表(DEV數據庫中的同一個表與一個TEST數據庫)之間的差異。每張桌子有〜30K行和〜5列。SQL EXCEPT性能

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 

查詢運行速度很快,並且執行計劃中沒有嵌套循環。

有人可以幫忙解釋一下嗎?我不明白爲什麼會有很大的差異。

+0

微軟SQL Server 2005 –

回答

3

我最好的猜測是優化做估計兩個表的基數(大小)方面做得很差。因爲它低估了大小,所以它產生了一個糟糕的查詢計劃。

在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) 

這消除嵌套循環的選項加入,選擇更有利的方法。

+0

我確認這是確切的情況。對其他數據庫執行相同的查詢時不會遇到嵌套循環,因此故障似乎在於SQL Server。 –

1

您的第一個查詢很慢,因爲您在where子句中將字段連接起來,這本質上是一個函數。這幾乎是你在where子句中運行函數的時間。這是一個更簡單的例子。這將很快。

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

這在邏輯上是相同的,但將是緩慢的

where cast(myDateTimeField as date) = @DateValue 
+0

謝謝,我選擇table1到兩個數據庫的臨時表中,並增加了一列field1 + field2,將查詢改爲使用臨時表,並解決了我的問題 –