Comparison of Dates in SQL

  • Amber.Brouillard (4/30/2009)


    Nevermind, as I look at it closer, I see your point. Thanks for the correction.

    Saints be praised 😉

  • TheSQLGuru (4/30/2009)


    ...there is also the same issue of index scan/seek if you are using a function on a column in a where clause.

    Unless you use the solution posted by Lynn and others:

    where

    referencedate >= dateadd(dd, datediff(dd, 0, @comparedate), 0) and -- Beginning of this day

    referencedate < dateadd(dd, datediff(dd, 0, @comparedate) + 1, 0) -- Beginning of next day

    AFAIK dateadd and datediff are functions 😛

    Generally it is true though!

    Paul

  • Paul White (4/30/2009)


    TheSQLGuru (4/30/2009)


    ...there is also the same issue of index scan/seek if you are using a function on a column in a where clause.

    Unless you use the solution posted by Lynn and others:

    where

    referencedate >= dateadd(dd, datediff(dd, 0, @comparedate), 0) and -- Beginning of this day

    referencedate < dateadd(dd, datediff(dd, 0, @comparedate) + 1, 0) -- Beginning of next day

    AFAIK dateadd and datediff are functions 😛

    Generally it is true though!

    Paul

    Reread my post Paul - I said using a function on a COLUMN. Your example is using a function on a VARIABLE. Just a slight difference there. :w00t:

    Best,
    Kevin G. Boles
    SQL Server Consultant
    SQL MVP 2007-2012
    TheSQLGuru on googles mail service

  • TheSQLGuru (4/30/2009)


    Reread my post Paul - I said using a function on a COLUMN. Your example is using a function on a VARIABLE. Just a slight difference there. :w00t:

    Ah. Yes. Well. :blush:

    A million apologies, deduct 100 smart-*** points from me!

    Maybe the next version of SQL Server will be able to constant-fold entire columns :laugh:

    Paul

  • I have gone through the entore thread. Could you please tell me how my solution is so suboptimal. Will it not work in any condition or will it be having a bad impact on performance. Just for better of my understanding...

    Thanks,

    Ashish

  • Ashish Pathak (5/1/2009)


    I have gone through the entore thread. Could you please tell me how my solution is so suboptimal. Will it not work in any condition or will it be having a bad impact on performance. Just for better of my understanding...

    Did you miss the entire discussion around using functions on columns and the effect that has on the ability of the optimizer to seek on an index rather than scan?

    How?

    :blink:

  • Ashish Pathak (5/1/2009)


    I have gone through the entore thread. Could you please tell me how my solution is so suboptimal. Will it not work in any condition or will it be having a bad impact on performance. Just for better of my understanding...

    Thanks,

    Ashish

    Like Paul said, the problem is that using a function on a column almost always prevents the use of an index seek (if an index is useable) and the engine must resort to an index scan (i.e. reading ALL of the index to find values, as opposed to very efficiently seeking down the btree to get the required rows). Another, sometimes incredibly damaging, issue is that statistics aren't usable either - which can lead to horribly inefficient query plans overall.

    I will say that in many, if not most, cases this issue isn't even noticed. There may not even be an index available, in which case all queries would have to use a table scan. Or the where clause would hit such a large portion of the rows that an index scan is more efficient. Or there simply aren't many rows in the table in which case an index seek might take 3 reads whereas a scan would take 100 - simply not a noticeable difference in most cases. But if you have 100M rows an index seek might take 5 or 6 reads but the scan could take tens of thousands - and THAT will leave a mark. 🙂

    Having said all that, there is still NO EXCUSE for writing suboptimal code like this once you know how to do it correctly. Yes, sometimes you have to be expedient in your coding to hit a deadline and taking shortcuts can allow you to write code faster. But this isn't one of those situations. It takes marginally more (if any) effort to do it correctly in this case.

    Best,
    Kevin G. Boles
    SQL Server Consultant
    SQL MVP 2007-2012
    TheSQLGuru on googles mail service

  • Using the DATEDIFF function works but can be very slow.

    I prefer using:

    DECLARE

    @FromDate DATETIME,

    @ThruDate DATETIME

    SET @FromDate = CONVERT(VARCHAR, GETDATE(), 101) --mm/dd/yyyy 00:00:00.000

    SET @ThruDate = DATEADD(DAY, 1, @FromDate)

    SET @ThruDate = DATEADD(MS, -3, @ThruDate) --mm/dd/yyyy 23:59:59.997

    SELECT * FROM Employee WHERE HireDate BETWEEN @FromDate AND @ThruDate

    Using -3 millliseconds will give you the maximum time Sql Server can use.

  • Ed (5/1/2009)


    Using the DATEDIFF function works but can be very slow.

    I prefer using:

    DECLARE

    @FromDate DATETIME,

    @ThruDate DATETIME

    SET @FromDate = CONVERT(VARCHAR, GETDATE(), 101) --mm/dd/yyyy 00:00:00.000

    SET @ThruDate = DATEADD(DAY, 1, @FromDate)

    SET @ThruDate = DATEADD(MS, -3, @ThruDate) --mm/dd/yyyy 23:59:59.997

    SELECT * FROM Employee WHERE HireDate BETWEEN @FromDate AND @ThruDate

    Using -3 millliseconds will give you the maximum time Sql Server can use.

    I'd prefer this:

    DECLARE

    @FromDate DATETIME,

    @ThruDate DATETIME

    SET @FromDate = dateadd(dd, datediff(dd, 0, getdate()), 0) --mm/dd/yyyy 00:00:00.000

    SET @ThruDate = dateadd(dd, 1, @FromDate)

    SELECT * FROM Employee WHERE HireDate >= @FromDate AND HireDate < @ThruDate;

  • Ed (5/1/2009)


    Using -3 millliseconds will give you the maximum time Sql Server can use.

    True with datetime, but no longer true on SQL 2008 if you start messing with the higher precision datetime data types. I've seen someone carry that 'convention' over to DATETIME2 and then wonder why they're missing rows.

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass
  • Does the hack with FLOATs from DATETIMEs still work with DATETIME2?

  • No. Nor the version that casts to int.

    DECLARE @Today2 DATETIME2 = GETDATE()

    SELECT CAST(FLOOR(CAST (@Today2 AS FLOAT)) AS DATETIME2)

    Msg 529, Level 16, State 2, Line 5

    Explicit conversion from data type datetime2 to float is not allowed.

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass
  • Alright, alright, point taken - no more converting to float... now I need to go explain the dateadd/datediff thing to my developers...

    I was hoping to be able to provide a nice UDF wrapper, but running Gail's test code from http://sqlinthewild.co.za/index.php/2008/09/04/comparing-date-truncations/, i find a 60X increase in CPU time when you add the UDF... 🙁

    Does that make sense? Can a UDF really be that expensive?

    (just in case I did something stupid, here is the function):

    CREATE FUNCTION dbo.fn_DayOnly_DateTime (@DateValue DateTime)

    RETURNS DateTime

    WITH SCHEMABINDING

    AS

    BEGIN

    RETURN dateadd(dd, datediff(dd,0, @DateValue),0)

    END

    GO

    http://poorsql.com for T-SQL formatting: free as in speech, free as in beer, free to run in SSMS or on your version control server - free however you want it.

  • Tao Klerks (5/1/2009)


    Alright, alright, point taken - no more converting to float... now I need to go explain the dateadd/datediff thing to my developers...

    I was hoping to be able to provide a nice UDF wrapper, but running Gail's test code from http://sqlinthewild.co.za/index.php/2008/09/04/comparing-date-truncations/, i find a 60X increase in CPU time when you add the UDF... 🙁

    Does that make sense? Can a UDF really be that expensive?

    (just in case I did something stupid, here is the function):

    CREATE FUNCTION dbo.fn_DayOnly_DateTime (@DateValue DateTime)

    RETURNS DateTime

    WITH SCHEMABINDING

    AS

    BEGIN

    RETURN dateadd(dd, datediff(dd,0, @DateValue),0)

    END

    GO

    Just for S & G's, try this with a CROSS APPLY:

    CREATE FUNCTION dbo.ufnDayOnly(@DateValue DateTime)

    RETURNS table

    AS

    RETURN dateadd(dd, datediff(dd,0, @DateValue),0) as DateOnly

    END

    GO

  • Tao Klerks (5/1/2009)


    Does that make sense? Can a UDF really be that expensive?

    Yes.

    Short answer. UDFs are not considered 'inline'. If they're run in a query, the run once for each row.

    Long answer - http://sqlinthewild.co.za/index.php/2009/04/29/functions-io-statistics-and-the-execution-plan/

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass

Viewing 15 posts - 91 through 105 (of 110 total)

You must be logged in to reply to this topic. Login to reply