Answered by:
Joining datetime column with date column

Question
-
Hi,
I am trying to generate a report rolled up to Month to date (MTD), Year to date (YTD) and Life to date (LTD) off of OLTP (not OLAP cubes). I am using the query below to do this.
But the table has 5mil + rows and the query executed for more than a day, inorder to improve performance I was planning to create a table which mimics date dimension in a star schema with a date column (on which jopin will be done) and other columns like yyyy, yyyymm. This way I can join payment table with the date dimension table and roll up based on yyyy and yyyymm columns which will be much faster as the optimizer will choose index seek instead of table scan.
The problem with this approach is the payment_table has datetime format (with up to milli sec accuracy) the date timension will have date in the format '2008-08-14 00:00:00.000' (one row per day) and my join will not work unless I populate the date dimension with all possible time with in a day which will run into billion + rows easily.
Is there any way I can achive better performance with what I am trying to do. This is on SQLserver 2005 (In 2008 MS introduced date datatype which is not there isn 2K5)
select * from
(
select customer_id, 'MTD' as record_type, count(*), sum(...), avg(...)
from payment_table
where
where year(payment_dt) = year(getDate())
and month(payment_dt) = month(getDate())
group by customer_id) MTD_payments
UNION ALL
(
select customer_id, 'YTD' as record_type, count(*), sum(...), avg(...)
from payment_table
where
where year(payment_dt) = year(getDate())
group by customer_id) YTD_payments
UNION ALL
(
select customer_id, 'LTD' as record_type, count(*), sum(...), avg(...)
from payment_table) LTD_payments
) payments_report
order by customer_id, record_type
Thursday, August 14, 2008 2:30 PM
Answers
-
Change first where clause
where year(payment_dt) = year(getDate())
and month(payment_dt) = month(getDate())
to
Code Snippetwhere
payment_dt >= dateadd(mm, datediff(mm, 0, getdate())+0, 0)and
payment_dt < dateadd(mm, datediff(mm, 0, getdate())+1, 0)change 2nd where clause
where year(payment_dt) = year(getDate())
to
Code Snippetwhere
payment_dt >= dateadd(yy, datediff(yy, 0, getdate())+0, 0)and
payment_dt < dateadd(yy, datediff(yy, 0, getdate())+1, 0)Denis The SQL Menace
ASP.NET hacks- Marked as answer by Suri Nagarajan Tuesday, April 7, 2009 8:06 PM
Thursday, August 14, 2008 2:50 PM
All replies
-
Change first where clause
where year(payment_dt) = year(getDate())
and month(payment_dt) = month(getDate())
to
Code Snippetwhere
payment_dt >= dateadd(mm, datediff(mm, 0, getdate())+0, 0)and
payment_dt < dateadd(mm, datediff(mm, 0, getdate())+1, 0)change 2nd where clause
where year(payment_dt) = year(getDate())
to
Code Snippetwhere
payment_dt >= dateadd(yy, datediff(yy, 0, getdate())+0, 0)and
payment_dt < dateadd(yy, datediff(yy, 0, getdate())+1, 0)Denis The SQL Menace
ASP.NET hacks- Marked as answer by Suri Nagarajan Tuesday, April 7, 2009 8:06 PM
Thursday, August 14, 2008 2:50 PM -
Thanks, the change you suggested made a huge difference, now the same query is running in 36 secs.Thursday, August 14, 2008 8:55 PM
-
That is because the query is sargable now, also see here: Query Optimizations With Dates
Denis The SQL Menace
Friday, August 15, 2008 12:55 PM