Based on my simple performance testing, I'm going to slightly change the version of my original function (see below).
IS NULL CASE IS NOT NULL UNION Case(ms) Empty Func fnMaxDate1 fnMaxDate2 fnMaxDate3 fnMaxDate4 0.01616 0.0446 0.0518 0.04934 0.05036 0.06177
The fastest function method is the CASE statement, but only approx. 0.003ms The slowest function is a function using the SELECT UNION "Pittsburgh DBA". I reordered my function to first check the most common result, which will check both arguments as IS NOT NULL. This change in logic leads to performance along with the CASE function.
Therefore, I refuse performance of 0.001ms for clarity of the IS NOT NULL function (see below).
Using the following script:
declare @d table(d1 date, d2 date); insert into @d values(null,null) , ('2/19/2012',null) , (null,'2/19/2012') , ('2/1/2012','2/15/2012') , ('2/1/2012','1/15/2012'); declare @md date , @i int=1 , @ts datetime2 , @ms0 int , @ms1 int , @ms3 int , @ms2 int , @ms4 int , @ms5 int ; -- case structure set @i=1; select @ts=GETDATE(); while @i<100000 begin select @md=case when ISNULL(d1,d2)<ISNULL(d2,d1) then ISNULL(d2,d1) else ISNULL(d1,d2) end from @d; set @i+=1; end select @ms0=DATEDIFF(ms,@ts,GETDATE()); -- fnMaxDate1, IF IS NULL set @i=1; select @ts=GETDATE(); while @i<100000 begin select @md=dbo.fnMaxDate1(d1,d2) from @d; set @i+=1; end select @ms1=DATEDIFF(ms,@ts,GETDATE()); -- fnMaxDate2, CASE set @i=1; select @ts=GETDATE(); while @i<100000 begin select @md=dbo.fnMaxDate2(d1,d2) from @d; set @i+=1; end select @ms2=DATEDIFF(ms,@ts,GETDATE()); -- fnMaxDate3, IF IS NOT NULL set @i=1; select @ts=GETDATE(); while @i<100000 begin select @md=dbo.fnMaxDate3(d1,d2) from @d; set @i+=1; end select @ms3=DATEDIFF(ms,@ts,GETDATE()); -- fnMaxDate4, SELECT UNION set @i=1; select @ts=GETDATE(); while @i<100000 begin select @md=dbo.fnMaxDate4(d1,d2) from @d; set @i+=1; end select @ms4=DATEDIFF(ms,@ts,GETDATE()); -- fnMaxDate5, empty function call set @i=1; select @ts=GETDATE(); while @i<100000 begin select @md=dbo.fnMaxDate5(d1,d2) from @d; set @i+=1; end select @ms5=DATEDIFF(ms,@ts,GETDATE()); select [Case(ms)] =@ms0 /100000.0, [fnMaxDate5 (empty function call)] =@ms5 /100000.0, fnMaxDate1=@ms1 /100000.0, fnMaxDate2=@ms2 /100000.0, fnMaxDate3 = @ms3/100000.0, fnMaxDate4=@ms4 /100000.0 go
Finally, here is the final version of the function:
ALTER FUNCTION [dbo].[fnMaxDate] ( @Date1 DATETIME, @Date2 DATETIME ) RETURNS DATETIME AS BEGIN DECLARE @Result DATETIME IF @Date1 IS NOT NULL AND @Date2 IS NOT NULL IF @Date1 >= @Date2 SET @Result = @Date1 ELSE SET @Result = @Date2 ELSE IF @Date1 IS NULL SET @Result = @Date2 ELSE IF @Date2 IS NULL SET @Result = @Date1 RETURN @Result END