SQL Server: Populate (Minute) Date Dimension table -
i'm working on script populate simple date dimension table granularity down minute level. table should contain smalldatetime representing every minute 1/1/2000 12/31/2015 23:59.
here definition table:
create table [dbo].[ref_minutedimension] ( [timestamp] smalldatetime not null, constraint [pk_ref_minutedimension] primary key clustered ([timestamp] asc) (fillfactor = 100) ); here latest revision of script:
declare @currenttimestamp smalldatetime; select top(1) @currenttimestamp = max([timestamp]) [dbo].[ref_minutedimension]; if @currenttimestamp not null set @currenttimestamp = dateadd(minute, 1, @currenttimestamp); else set @currenttimestamp = '1/1/2000 00:00'; alter table [dbo].[ref_minutedimension] drop constraint [pk_ref_minutedimension]; while @currenttimestamp < '12/31/2050 23:59' begin ;with dateindex ([timestamp]) ( select @currenttimestamp union select dateadd(minute, 1, [timestamp]) dateindex di di.[timestamp] < dbo.fgetyearend(@currenttimestamp) ) insert [dbo].[ref_minutedimension] ([timestamp]) select di.[timestamp] dateindex di option (maxrecursion 0); set @currenttimestamp = dateadd(year, 1, dbo.fgetyearbegin(@currenttimestamp)) end alter table [dbo].[ref_minutedimension] add constraint [pk_ref_minutedimension] primary key clustered ([timestamp] asc) (fillfactor = 100); a couple of things point out:
- i've added logic drop , subsequently re-add primary key constraint on table, hoping boost performance.
- i've added logic chunk
insertsyearly batches minimize impact on transaction log. on side note, we're usingsimplerecovery model.
performance so-so , takes around 15-20 minutes complete. hints/suggestions on how script "tuned up" or improved?
also, completeness here fgetyearbegin , fgetyearend:
create function dbo.fgetyearbegin ( @dtconvertdate datetime ) returns smalldatetime begin return dateadd(year, datediff(year, 0, @dtconvertdate), 0) end create function dbo.fgetyearend ( @dtconvertdate datetime ) returns smalldatetime begin return dateadd(minute, -1, dateadd(year, 1, dbo.fgetyearbegin(@dtconvertdate))) end
this takes 11 seconds on server...
if object_id('tempdb..#somenumbers') not null drop table #somenumbers; create table #somenumbers (id int); declare @minutes int, @days int; select @minutes = datediff(minute,'1/1/2000 00:00','1/2/2000 00:00'), @days = datediff(day,'1/1/2000 00:00','1/1/2051 00:00'); base ( select 1 seedid union select 1 ), build ( select seedid base union select b.seedid + 1 build b cross join base b2 b.seedid < 14 ) insert #somenumbers select row_number() on (order seedid) id build option (maxrecursion 0); if object_id('tempdb..#values') not null drop table #values; create table #values ([timestamp] smalldatetime not null); dates ( select dateadd(day,id-1,'1/1/2000 00:00') [timestamp] #somenumbers id <= @days ) insert #values select convert(smalldatetime,dateadd(minute,id-1,[timestamp])) dates d join #somenumbers sn on sn.id <= @minutes order 1
This comment has been removed by the author.
ReplyDeletecan you explain you code which is taking 11 sec ?
ReplyDelete