@mbhandari: Glad we could help!
Life got pesky, so it took me longer than I wanted to post the comparison of the IF EXISTS and IF COUNT(*)>0 queries, but here it is.
--Create our wonderful test table
CREATE TABLE ExistsVSCount (
SomeNumber int
)
GO
--Populate our test table with 100,000 instances of each of the integers from 1 to 10
WITH N (SomeNumber) AS (
SELECT 1
UNION ALL
SELECT 2
UNION ALL
SELECT 3
UNION ALL
SELECT 4
UNION ALL
SELECT 5
UNION ALL
SELECT 6
UNION ALL
SELECT 7
UNION ALL
SELECT 8
UNION ALL
SELECT 9
UNION ALL
SELECT 10
)
INSERT INTO ExistsVSCount (SomeNumber)
SELECT N1.SomeNumber
FROM N AS N1
CROSS JOIN N AS N2
CROSS JOIN N AS N3
CROSS JOIN N AS N4
CROSS JOIN N AS N5
CROSS JOIN N AS N6
--Let's check the number of pages in our newly populated heap. For me it says we have 3,345 data pages.
--We'll remember that for later.
SELECT au.data_pages FROM sys.tables AS t
INNER JOIN sys.indexes AS i ON t.object_id=i.object_id
INNER JOIN sys.partitions AS p ON i.object_id=p.object_id
INNER JOIN sys.allocation_units AS au ON au.container_id=p.partition_id
WHERE t.name='ExistsVSCount'
--Make sure we see the glorious IO stats
SET STATISTICS IO ON
--Check for the existence of values larger than 8 using IF EXISTS and SELECT TOP
IF EXISTS
(SELECT TOP (1) SomeNumber FROM ExistsVSCount WHERE SomeNumber>8)
SELECT 'There''s something larger than eight!'
--IO stats showed the following:
--Table 'ExistsVSCount'. Scan count 1, logical reads 268, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Check for the existence of values larger than 8 using IF SELECT COUNT(*)...>0
--A terrible idea, because we'll just scan the whole table, right?
IF (SELECT COUNT(*) FROM ExistsVSCount WHERE SomeNumber>8)>0
SELECT 'There''s something larger than eight!'
--IO Stats for this one:
--Table 'ExistsVSCount'. Scan count 1, logical reads 268, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Ok, so those are exactly the same, reading less than 10% of the table.
--The exact number of logical reads for these two will vary a bit if the script is run multiple times, but this run seemed representative.
--Looks like the optimizer was clever enough, as expected.
--Let's now get some confirmation that this is an optimization specifically for IF (SELECT COUNT(*)...>0, by switching that to >1
IF (SELECT COUNT(*) FROM ExistsVSCount WHERE SomeNumber>8)>1
SELECT 'There''s something larger than eight!'
--IO Stats for this one:
--Table 'ExistsVSCount'. Scan count 1, logical reads 3345, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Ah, now we're seeing what we originally thought would happen, and reading all 3,345 data pages in the heap.
--Clean up after ourselves
SET STATISTICS IO OFF
DROP TABLE ExistsVSCount
In short, the optimizer does indeed run them in exactly the same way.
The actual execution plans for each are attached.
The specific example above was run on 2008, but I tested and saw the same behavior on 2005, 2008 R2, 2012, and 2014 as well.
I'd still prefer the IF EXISTS, just because it's actually expressing the more efficient logic, while the COUNT(*)>0 is relying on a trick from the optimizer, but it does seem that they run in exactly the same way.
Cheers!