Tell me more ×
Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

In SQL Server 2008 the datatype date datatype was added.

In this connect item you can see that casting a datetime column to date is sargable and may use an index on the datetime column.

select *
from T
where cast(DateTimeCol as date) = '20130101';

The other option you have is to use a range instead.

select *
from T
where DateTimeCol >= '20130101' and
      DateTimeCol < '20130102'

Are these queries equally good or should one be preferred over the other?

SQL Fiddle

share|improve this question
1  
What does the execution plan say? – a_horse_with_no_name Feb 4 at 8:31
hi mikel, is this website only for database question? – Freelancer Apr 10 at 11:46
@Freelancer Yes, that is the idea. Have a look at the FAQ to see what is on topic here. – Mikael Eriksson Apr 10 at 11:48
Thank you mikael. – Freelancer Apr 10 at 11:49
1  
@Freelancer Nope, the points are separate.' – Mikael Eriksson Apr 10 at 11:54
show 1 more comment

1 Answer

up vote 9 down vote accepted

The mechanism behind the sargability of casting to date is called dynamic seek.

One disadvantage of relying on it is that the cardinality estimates may not be as accurate as with the traditional range query. This can be seen in an amended version of your SQL Fiddle.

All 256 rows in the table now match the predicate (with datetimes 1 minute apart all on the same day).

The second (range) query correctly estimates that 256 will match and uses a clustered index scan. The CAST( AS DATE) query incorrectly estimates that only one row will match and produces a plan with key lookups.

I'm not sure where the 1 row estimate comes from. The statistics aren't ignored completely. If all rows in the table have the same datetime and it matches the predicate (e.g. 20130101 00:00:00 or 20130101 01:00:00) then the plan shows a clustered index scan with an estimated 64 rows (25%).

If all rows in the table have the same datetime and it doesn't match the predicate (e.g. 20130102 01:00:00) then it falls back to the estimated row count of 1 and the plan with lookups.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.