Question

Every now and then I see these being used, but it never seems to be anything that can't be performed as equally well, if not better, by using a normal join or subquery.

I see them as being misleading (they're arguably harder to accurately visualize compared to conventional joins and subqueries), often misunderstood (e.g. using SELECT * will behave the same as SELECT 1 in the EXISTS/NOT EXISTS subquery), and from my limited experience, slower to execute.

Can someone describe and/or provide me an example where they are best suited or where there is no option other than to use them? Note that since their execution and performance are likely platform dependent, I'm particularly interested in their use in MySQL.

Was it helpful?

Solution

Every now and then I see these being used, but it never seems to be anything that can't be performed as equally well, if not better, by using a normal join or subquery.

This article (though SQL Server related):

may be of interest to you.

In a nutshell, JOIN is a set operation, while EXISTS is a predicate.

In other words, these queries:

SELECT  *
FROM    a
JOIN    b
ON      some_condition(a, b)

vs.

SELECT  *
FROM    a
WHERE   EXISTS
        (
        SELECT  NULL
        FROM    b
        WHERE   some_condition(a, b)
        )

are not the same: the former can return more than one record from a, while the latter cannot.

Their counterparts, NOT EXISTS vs. LEFT JOIN / IS NULL, are the same logically but not performance-wise.

In fact, the former may be more efficient in SQL Server:

OTHER TIPS

if the main query returned much less rows then the table where you want to find them. example:

SELECT st.State
FROM states st
WHERE st.State LIKE 'N%' AND EXISTS(SELECT 1 FROM addresses a WHERE a.State = st.State)

doing this with a join will be much slower. or a better example, if you want to search if a item exists in 1 of multiple tables.

You can't [easily] use a join in an UPDATE statement, so WHERE EXISTS works excellently there:

UPDATE mytable t
   SET columnX = 'SomeValue'
 WHERE EXISTS 
   (SELECT 1 
      FROM myothertable ot
     WHERE ot.columnA = t.columnY
       AND ot.columnB = 'XYX'
   );

Edit: Basing this on Oracle more than MySQL, and yes there are ways to do it with an inline view, but IMHO this is cleaner.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top