Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL EXCEPT performance

I'm trying to use a query similar to the following query to find differences between two tables (the same table in a DEV database vs a TEST database). Each table has ~30K rows and ~5 columns.

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 is char(5) and field2 is char(1)

This query essentially never terminates.

When i analyze this query using SET SHOWPLAN_ALL ON, I can see there is a nested loop pretty high in the tree. When I change the above query to

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

The query runs quickly and there is no nested loop in the execution plan.

Can someone help explain this? I don't understand why there would be a drastic difference.

like image 668
Noble Shore Avatar asked Dec 21 '25 10:12

Noble Shore


1 Answers

My best guess is that the optimizer is doing a poor job of estimating the cardinality (size) of the two tables. Because it underestimates the size, it is generating a poor query plan.

In SQL Server, you can use join hints on except. So, you can get the query you want with:

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)

This eliminates the option of the nested loop join, choosing a more favorable method.

like image 126
Gordon Linoff Avatar answered Dec 23 '25 23:12

Gordon Linoff



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!