There is no way anyone can tell you that EXCEPT
will always or never out-perform an equivalent OUTER JOIN
. The optimizer will choose an appropriate execution plan regardless of how you write your intent.
That said, here is my guideline:
Use EXCEPT
when at least one of the following is true:
- The query is more readable (this will almost always be true).
- Performance is improved.
And BOTH of the following are true:
- The query produces semantically identical results, and you can demonstrate this through sufficient regression testing, including all edge cases.
- Performance is not degraded (again, in all edge cases, as well as environmental changes such as clearing buffer pool, updating statistics, clearing plan cache, and restarting the service).
It is important to note that it can be a challenge to write an equivalent EXCEPT
query as the JOIN
becomes more complex and/or you are relying on duplicates in part of the columns but not others. Writing a NOT EXISTS
equivalent, while slightly less readable than EXCEPT
should be far more trivial to accomplish - and will often lead to a better plan (but note that I would never say ALWAYS
or NEVER
, except in the way I just did).
In this blog post I demonstrate at least one case where EXCEPT
is outperformed by both a properly constructed LEFT OUTER JOIN
and of course by an equivalent NOT EXISTS
variation.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…