I'm writing a trigger that is doing
IF (@A <> @B) ... but this will not work for NULL values on either @A or @B. The way it's normally done is
IF (@A <> @B) OR (@A IS NOT NULL AND @B IS NULL) OR (@A IS NULL AND @B IS NOT NULL) but this involves up to 9 comparisons versus 1!
I could do
SET ANSI_NULLS OFF but apparently this is not recommended (and to be deprecated).
So what is the best solution for this? Just take 9 comparisons for a simple inequality check when it should be 1? The trigger is not performance critical, but it does need to be fast. When batch loading, this could slow it down considerably.
PEFORMANCE TESTS
Here are the results of a performance test that checks for inequality a million times such that 90% of the time the values are not equal, 10% of the time each value may be null.
IF (@A <> @B) OR (@A IS NULL AND @B IS NOT NULL) OR (@A IS NOT NULL AND @B IS NULL) Result: average 3848ms
IF (ISNULL(@A, 0) <> ISNULL(@B, 0)) Result: average 3942ms
IF (@A = @B) GOTO Equal ELSE IF @A IS NULL AND @B IS NULL GOTO Equal Result: average 4140ms
IF EXISTS (SELECT @A EXCEPT SELECT @B) Result: average 7795ms
The times don't really matter, it's the relative difference that counts. Clearly, the classic approach is the fastest. Likely MSSQL has internally optimised for this type of check.
Test run on MacBook Pro (Intel Core 2 Duo, 2.4Ghz, 8GB RAM inside a Vista VM running MSSQL 2008 Express).