|
Quite often I have a need to generate reports that show the days of a month with counts, sums, averages, etc by day. I also get a lot of requests to show each of the days of the month regardless of the fact there might be any data for that day. I have gone down the route of creating a table, putting in +/- 100 years of dates or whatever and then done a join but I tried some code from this article that creates a CTE dates table for the values I specify. I have shown the code here...
This uses a recursion to generate but even when I specified a from date of '20000101' and an end date of '20100219' it ran in under a second. Would this be a better method than holding large tables of dates on the server? Pros/cons please guys.
(comments are locked)
|
|
I would never use recursion for such a thing... let's start to look at why... (I've never posted code on this forum before so bear with me if I mess up the formatting)...
The profiler output on those 3 runs pretty much tells the story of "pros" and "cons". But there's more to it than just shear speed and resource effeciency. Let's think about this for a minute... these 3 examples are only for 365 rows. What if someone decides they want to put the Tally-on-the-fly code into a user defined function and then use it to calculate against a million row table? They find some "really cool" code like a recursive CTE and put it into their function (whatever it does). The recursive CTE is at least 38 times slower than either of the other two methods and on a million rows and in a function, that's going to make for a very large difference in performance. My feeling is that there are simply no "pros" to using a recursive CTE for this type of thing even on very small numbers of rows because some poor slob might find the code and use it for something bigger. Yes, there are pros to the cross joined CTE method (second method) but even the Calendar table method just absolutely blows the doors off the Recursive CTE method. Build a temporary calendar table on the fly using a CTE if you want... the pros to doing that are controllable size and you don't have to fight a DBA who may be "disk stingy". Just don't ever use recursion to do it. --Jeff Moden As a side bar, I don't know who picked the colors for the code in the code boxes but I'd really like to take them out for a nice steaming hot pork chop dinner. ;-)
Feb 20 '10 at 01:59 AM
Jeff Moden
+1 Marked as the answer Jeff. Thank you for the fantastic explanation. I agree with you on the colours there was some discussion about changing them to match SSMS which would help my eyes somewhat! Check out http://ask.sqlservercentral.com/questions/95/prettifying-code-to-give-it-the-same-colourization-as-ssms for more details.
Feb 20 '10 at 05:34 AM
Ian Roke
Thanks for the leg up and the great feedback, Ian. ;-)
Feb 25 '10 at 04:00 AM
Jeff Moden
(comments are locked)
|
|
A permanent table means you can join it in there, without calculations to build the dates. I would think there is some performance hit for his. The other pro that I've seen is that you can "mark" days as business days. It's one thing to know the weekdays v weekends, but knowing accounting periods, holidays, etc. are easy to include/exclude in a join if you have flags. In terms of cons, you have one table, you have possible maintenance, and you use space. Good points. Also, in general the permenant table will be faster, especially if properly indexed. Of course, that speed difference may be very small or mean very little on a machine that is not being stressed.
Feb 19 '10 at 02:12 PM
TimothyAWiseman
That's actually not been my experience with things like on-the-fly Tally tables, Timothy. I've found that they're a pretty close match. Admittedly, I've not tried the same thing with Calendar tables. We'd have to do a test before I say for sure one way or another.
Feb 25 '10 at 04:02 AM
Jeff Moden
(comments are locked)
|
|
Permanent calendar tables :
On-the fly method :
(comments are locked)
|
|
It depends! Personally I tend to use an inline udf to build date ranges - because generally the reports I have written don't limit themselves to days - so I would pass in as parameters both the increment and step type - so if I wanted a result set for a week in 15 minute intervals, no problem. If I wanted a weekly set, again no problem. However I would look at lynn pettis' article about dynamic tally tables as that uses a much more efficient method of table building using cte's - recursing once per result row is probably not the way to go...
(comments are locked)
|

