• GSquared (12/17/2012)


    Something that many don't know about SARGability is that some functions, regardless of side of equation in a Where clause, are SARGable.

    Try this:

    SET NOCOUNT ON;

    USE ProofOfConcept;

    GO

    CREATE TABLE dbo.SARGTest (

    DT DATETIME NOT NULL);

    GO

    CREATE CLUSTERED INDEX CID_SARGTest_DT ON dbo.SARGTest(DT);

    GO

    INSERT INTO dbo.SARGTest(DT)

    SELECT TOP (1000000) DATEADD(DAY, CHECKSUM(NEWID())%10000, GETDATE())

    FROM ProofOfConcept.dbo.Numbers AS N1

    CROSS JOIN ProofOfConcept.dbo.Numbers AS N2;

    GO

    Also tested:

    DECLARE @s-2 DATE = GETDATE(), @E DATE = DATEADD(DAY, 1, GETDATE());

    SELECT *

    FROM dbo.SARGTest

    WHERE DT >= @s-2 AND DT < @E;

    Still get a seek. (See Plan2.sqlplan, attached.)

    I guess that the quoted part was written because of my previous message about the fact that using variables, assign them values and then use them in the same scope in the where clause will cause the server to do a table scan instead of seek operation. If I'm correct, then let be clearer about it. If you use a clustered index, then seek operation will be used. If you'll use an appropriate none clustered index that is also a covering index to this query, then you'll get seek operation. If you'll use none clustered index that is not covering, then most times you will get scan operation. In your example you had a table with one column and a clustered that is based on this column. Here is an example that is based on the code that you've added to your message:

    CREATE TABLE dbo.SARGTest (

    DT DATETIME NOT NULL, filler char(1) default ('a'));

    GO

    INSERT INTO dbo.SARGTest(DT)

    SELECT TOP (1000000) DATEADD(DAY, CHECKSUM(NEWID())%10000, GETDATE())

    FROM sys.objects

    CROSS JOIN sys.objects as s2

    CREATE INDEX CID_SARGTest_DT ON dbo.SARGTest(DT);

    DECLARE @s-2 datetime

    declare @E datetime

    SET @s-2 = GETDATE()

    SET @E = DATEADD(DAY, 1, GETDATE())

    --Using the varibles cause table scan

    SELECT *

    FROM dbo.SARGTest

    WHERE DT >= @s-2 AND DT < @E;

    --Using the same values but without the varibles use a table seek

    SELECT *

    FROM dbo.SARGTest

    where DT > GETDATE() AND DT < DATEADD(DAY, 1, GETDATE())

    go

    drop table SARGTest

    --------------------------------------------------------------
    To know how to ask questions and increase the chances of getting asnwers:
    http://www.sqlservercentral.com/articles/Best+Practices/61537/

    For better answers on performance questions, click on the following...
    http://www.sqlservercentral.com/articles/SQLServerCentral/66909/