I have the following SQL:
IF EXISTS
(
SELECT
1
FROM
SomeTable T1
WHERE
SomeField = 1
AND SomeOtherField = 1
AND NOT EXISTS(SELECT 1 FROM SomeOtherTable T2 WHERE T2.KeyField = T1.KeyField)
)
RAISERROR ('Blech.', 16, 1)
The SomeTable
table has around 200,000 rows, and the SomeOtherTable
table has about the same.
If I execute the inner SQL (the SELECT
), it executes in sub-second time, returning no rows. But, if I execute the entire script (IF...RAISERROR
) then it takes well over an hour. Why?
Now, obviously, the execution plan is different - I can see that in Enterprise Manager - but again, why?
I could probably do something like SELECT @num = COUNT(*) WHERE
... and then IF @num > 0 RAISERROR
but... I think that's missing the point somewhat. You can only code around a bug (and it sure looks like a bug to me) if you know that it exists.
EDIT:
I should mention that I already tried re-jigging the query into an OUTER JOIN as per @Bohemian's answer, but this made no difference to the execution time.
EDIT 2:
I've attached the query plan for the inner SELECT
statement:
... and the query plan for the whole IF...RAISERROR
block:
Obviously these show the real table/field names, but apart from that the query is exactly as shown above.