tags:

views:

969

answers:

7

I've seen some people use EXISTS (SELECT 1 FROM ...) rather than EXISTS (SELECT id FROM ...) as an optimization--rather than looking up and returning a value, SQL Server can simply return the literal it was given.

Is SELECT(1) always faster? (I can imagine this making a difference if the field is a large VARCHAR, but is there a performance difference when the field is an INT?)

+1  A: 

Yes, because when you select a literal it does not need to read from disk (or even from cache).

John Millikin
This is wrong, see: http://stackoverflow.com/questions/1597442/subquery-using-exists-1-or-exists/
Matt Rogish
+1  A: 

doesn't matter what you select in an exists clause. most people do select *, then sql server automatically picks the best index

Darren Kopp
+4  A: 

When you use SELECT 1, you clearly show (to whoever is reading your code later) that you are testing whether the record exists. Even if there is no performance gain (which is to be discussed), there is gain in code readability and maintainability.

Milan Babuškov
This is a good point. Slightly off-topic from the question, but I agree with the idea.
TSomKes
A: 

Select 1 should be better to use in your example. Select * gets all the meta-data assoicated with the objects before runtime which adss overhead during the compliation of the query. Though you may not see differences when running both types of queries in your execution plan.

ImJustPondering
+6  A: 

In SQL Server, it does not make a difference whether you use SELECT 1 or SELECT * within EXISTS. You are not actually returning the contents of the rows, but that rather the set determined by the WHERE clause is not-empty. Try running the query side-by-side with SET STATISTICS IO ON and you can prove that the approaches are equivalent. Personally I prefer SELECT * within EXISTS.

jalbert
Agree. I just find WHERE EXISTS (SELECT * FROM ...) more readable. It's more intuitive - that you're just checking that the record exists and nothing more. WHERE EXISTS (SELECT 1 FROM ...) just seems unnatural. All a subjective opinion of course.
njreed.myopenid.com
+1  A: 

As someone pointed out sql server ignores the column selection list in EXISTS so it doesn't matter. I personally tend to use "SELECT null ..." to indicate that the value is not used at all.

A: 

For google's sake, I'll update this question with the same answer as this one (http://stackoverflow.com/questions/1597442/subquery-using-exists-1-or-exists/) since (currently) an incorrect answer is marked as accepted. Note the SQL standard actually says that EXISTS via * is identical to a constant.

No. This has been covered a bazillion times. SQL Server is smart and knows it is being used for an EXISTS, and returns NO DATA to the system.

Quoth Microsoft: http://technet.microsoft.com/en-us/library/ms189259.aspx?ppud=4

The select list of a subquery introduced by EXISTS almost always consists of an asterisk (*). There is no reason to list column names because you are just testing whether rows that meet the conditions specified in the subquery exist.

Also, don't believe me? Try running the following:

SELECT whatever
  FROM yourtable
 WHERE EXISTS( SELECT 1/0
                 FROM someothertable 
                WHERE a_valid_clause )

If it was actually doing something with the SELECT list, it would throw a div by zero error. It doesn't.

EDIT: Note, the SQL Standard actually talks about this.

ANSI SQL 1992 Standard, pg 191 http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt

     3) Case:

        a) If the <select list> "*" is simply contained in a <subquery> that is immediately contained in an <exists predicate>, then the <select list> is equivalent to a <value expression> that is an arbitrary <literal>.
Matt Rogish