views:

19

answers:

1

I'm creating a robust date table want to know the best way to link to it. The Primary Key Clustered Index will be on the smart date integer key (per Kimball spec) with a name of DateID. Until now I have been running queries against it like so:

select Foo.orderdate -- a bunch of fields from Foo
      ,DTE.FiscalYearName
      ,DTE.FiscalPeriod
      ,DTE.FiscalYearPeriod
      ,DTE.FiscalYearWeekName
      ,DTE.FiscalWeekName  
      FROM SomeTable Foo
     INNER JOIN
       DateDatabase.dbo.MyDateTable DTE
     ON DTE.date = CAST(FLOOR(CAST(Foo.forderdate AS FLOAT)) AS DATETIME)

Keep in mind that Date is a nonclustered index field with values such as: 2000-01-01 00:00:00.000

It just occured to me that since I have a clustered integer index (DATEID) that perhaps I should be converting the datetime in my database field to match it and linking based upon that field.

What do you folks think?

Also, depending on your first answer, if I am typically pulling those fields from the date table, what kind of index how can I optimize the retrieval of those fields? Covering index?

+1  A: 

Even without changing the database structure, you'd get much better performance using a date range join like this:

select Foo.orderdate -- a bunch of fields from Foo 
  ,DTE.FiscalYearName 
  ,DTE.FiscalPeriod 
  ,DTE.FiscalYearPeriod 
  ,DTE.FiscalYearWeekName 
  ,DTE.FiscalWeekName   
  FROM SomeTable Foo 
 INNER JOIN 
   DateDatabase.dbo.MyDateTable DTE 
 ON Foo.forderdate >= DTE.date AND Foo.forderdate < DATEADD(dd, 1, DTE.date)

However, if you can change it so that your Foo table includes a DateID field then, yes, you'd get the best performance by joining with that instead of any converted date value or date range.

If you change it to join on DateID and DateID is the first column of the clustered index of the MyDateTable then it's already covering (a clustered index always includes all other fields).

Daniel Renshaw
So, what is the most performant way to convert a date time to smart date key INT type?
DavidStein
Are you talking about changing the database structure or not? If you are talking about changing the structure, I wouldn't convert the datetime, I'd add an additional DateID column to Foo and populate it with the correct value when records are inserted (plus a one-off batch opp to enter values for existing records). If you're not thinking of changing the database structure, I'd stick with the date range approach I put in my answer.
Daniel Renshaw
I'm sorry, I missed that question. The Date Table already has a primary key clustered index on an INT field called DateID. DateID is a smart date field meaning that today's date would show up as 20100901 (September 1st).
DavidStein
I'm not sure what you mean by "smart date field". If you're simply after a way to convert a `datetime` value into an int structured in the way you describe, try `DATEPART(year, orderdate) * 10000 + DATEPART(month, orderdate) * 100 + DATEPART(day, orderdate)`.
Daniel Renshaw
Thanks, I'm going to split that part off into a different question to make sure people see it. I appreciate your help.
DavidStein