NOTE: While my advice was true many years ago, Oracle's optimizer has improved so that the location of the where definitely no longer matters here. However preferring UNION ALL
vs UNION
will always be true, and portable SQL should avoid depending on optimizations that may not be in all databases.
Short answer, you want the WHERE
before the UNION
and you want to use UNION ALL
if at all possible. If you are using UNION ALL
then check the EXPLAIN output, Oracle might be smart enough to optimize the WHERE
condition if it is left after.
The reason is the following. The definition of a UNION
says that if there are duplicates in the two data sets, they have to be removed. Therefore there is an implicit GROUP BY
in that operation, which tends to be slow. Worse yet, Oracle's optimizer (at least as of 3 years ago, and I don't think it has changed) doesn't try to push conditions through a GROUP BY
(implicit or explicit). Therefore Oracle has to construct larger data sets than necessary, group them, and only then gets to filter. Thus prefiltering wherever possible is officially a Good Idea. (This is, incidentally, why it is important to put conditions in the WHERE
whenever possible instead of leaving them in a HAVING
clause.)
Furthermore if you happen to know that there won't be duplicates between the two data sets, then use UNION ALL
. That is like UNION
in that it concatenates datasets, but it doesn't try to deduplicate data. This saves an expensive grouping operation. In my experience it is quite common to be able to take advantage of this operation.
Since UNION ALL
does not have an implicit GROUP BY
in it, it is possible that Oracle's optimizer knows how to push conditions through it. I don't have Oracle sitting around to test, so you will need to test that yourself.