Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Data Management

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

    Search

    XML Feeds

    Google Ads

    « How Does Between Work With Dates In SQL Server?SQL Server 2008 geography data type screencasts on Channel 9 »
    comments

    I was reading Itzik Ben-Gan's An Introduction to New T-SQL Programmability Features in SQL Server 2008 article yesterday after one of my friends allerted me to the following from that article
    For example, the plan for the following query performs an index seek on the index on the CurrencyRateDate DATETIME column:

    1. USE AdventureWorks;
    2.  
    3. SELECT FromCurrencyCode, ToCurrencyCode, EndOfDayRate
    4.  
    5. FROM Sales.CurrencyRate
    6.  
    7. WHERE CAST(CurrencyRateDate AS DATE) = '20040701';

    I was surprised by this, as we all know functions/conversions on column names are generaly bad for performance.

    Let's see how this works. First create this table in the tempdb database.

    1. use tempdb
    2.  
    3. go
    4.  
    5. create table TestDatetimePerf (SomeCol datetime,id int identity)
    6.  
    7. go

    This will insert 2048 rows with dates between 2008-01-01 12 AM and 2008-03-26 7 AM

    1. insert TestDatetimePerf(SomeCol)
    2.  
    3. select dateadd(hh,number,'20080101')
    4.  
    5. from master..spt_values
    6.  
    7. where type ='P'
    8.  
    9. go
    10.  
    11. create index ix_Date on TestDatetimePerf(SomeCol)
    12.  
    13. go

    Turn on the execution plan

    1. set showplan_text on
    2.  
    3. go

    Execute the following query

    1. select *
    2.  
    3. from TestDatetimePerf
    4.  
    5. where convert(varchar(30),SomeCol,112) = '20080103'

    Here is the plan

    1. |--Table Scan(OBJECT:([tempdb].[dbo].[TestDatetimePerf]),
    2. --WHERE:(CONVERT(varchar(30),[tempdb].[dbo].[TestDatetimePerf].[SomeCol],112)=[@1]))

    As you can see that results in a scan.

    What happens when you convert to date?

    1. select *
    2.  
    3. from TestDatetimePerf
    4.  
    5. where convert(date,SomeCol) = '20080103'

    Here is the plan

    1. |--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1000]))
    2. |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1007], [Expr1008], [Expr1006]))
    3. | |--Compute Scalar(DEFINE:(([Expr1007],[Expr1008],[Expr1006])=GetRangeThroughConvert('2008-01-03','2008-01-03',(62))))
    4. | | |--Constant Scan
    5. | |--Index Seek(OBJECT:([tempdb].[dbo].[TestDatetimePerf].[ix_Date]),
    6. --SEEK:([tempdb].[dbo].[TestDatetimePerf].[SomeCol] > [Expr1007]
    7. --AND [tempdb].[dbo].[TestDatetimePerf].[SomeCol] < [Expr1008]),
    8. --WHERE:(CONVERT(date,[tempdb].[dbo].[TestDatetimePerf].[SomeCol],0)='2008-01-03') ORDERED FORWARD)
    9. |--RID Lookup(OBJECT:([tempdb].[dbo].[TestDatetimePerf]), SEEK:([Bmk1000]=[Bmk1000]) LOOKUP ORDERED FORWARD)

    See that? You get a seek instead, very interesting. It would be nice that when you use convert with the style optional parameter that the optimizer would be smart enough to convert that also to a seek.

    About the Author

    User bio imageDenis has been working with SQL Server since version 6.5. Although he worked as an ASP/JSP/ColdFusion developer before the dot com bust, he has been working exclusively as a database developer/architect since 2002. In addition to English, Denis is also fluent in Croatian and Dutch, but he can curse in many other languages and dialects (just ask the SQL optimizer) He lives in Princeton, NJ with his wife and three kids.
    Social SitingsTwitterFacebookLinkedInHomePageFlickrLTD RSS Feed
    3042 views
    InstapaperVote on HN

    2 comments

    Comment from: Dave [Visitor]
    *****
    Dave I just wanted to point out that when using the Select All option to copy and paste into SQL Management Studio, the " ' " around the date is not correct for some reason. Just wanted to let you know.
    10/24/08 @ 14:09
    Comment from: SQLDenis [Member] Email
    SQLDenis Dave I fixed it, it was a smart quotes plugin that caused it
    11/08/09 @ 06:35

    Leave a comment


    Your email address will not be revealed on this site.

    To mislead the spambots.

    Your URL will be displayed.
    (Line breaks become <br />)
    (Name, email & website)
    (Allow users to contact you through a message form (your email will not be revealed.)