When given a randomly behaving query the other day, I discovered something I thought interesting when testing for inequality.To recreate it we'll have to generate a table of GUIDs with a clustered index.CREATE TABLE [dbo].[guids] ( [guid] [UNIQUEIDENTIFIER] NOT NULL, [id] [int] IDENTITY(1,1) NOT NULL CONSTRAINT [PK_guid] PRIMARY KEY CLUSTERED ([id]));GOINSERT [dbo].[guids] (guid)SELECT NEWID();GO 1000Example 1, below, returns exactly what you'd expect: a record count of 1000./* Example 1 */SELECT COUNT(*)FROM guids gWHERE g.guid <> NEWID() In Example 2, below, I expected a count of 990./* Example 2 */SELECT COUNT(*)FROM guids gWHERE g.guid <> NEWID() AND g.id > 10To my surprise, it returns a different number each time!This is because the optimizer is evaluating the inequality test as: [i]g.guid > NEWID() OR g.guid < NEWID()[/i]Because NEWID() is a non-deterministic function (returning different value each time it is called with the same input), this optimization results in a comparison of two different guids. Although g.guid is NEVER equal to NEWID(), in some cases g.guid IS > than one NEWID() and IS < the other NEWID()!Interestingly, Example 1 does not do this because without the secondary test on the clustered index the optimizer actually uses an inequality test you'd expect:[i]g.guid <> NEWID()[/i]Additional testing showed that if the secondary test (g.id > 10) was done on a non-clustered index, the optimizer evaluates the inequality test as:[i]g.guid <> NEWID()[/i]The only time the optimizer evaluates the inequality test as > OR < is if there is a test with the clustered index in the query.Finally, if an implicit conversion is present in the inequality test, the optimizer evaluates the expression as expected:g.guid <> CAST(NEWID() AS VARCHAR(50)) evaluates as:[i]g.guid <> CONVERT_IMPLICIT(UNIQUEIDENTIFIER, CONVERT(VARCHAR(50), NEWID(), 0), 0)[/i][b]Summary[/b]Be careful when using functions and inequality testing. If the function is deterministic your query may be evaluating it twice for each test. Furthermore, if the function is non-deterministic you may get unexpected results.
↧