TSQL DateTime到DateKey Int

时间:2012-04-10 15:28:24

标签: tsql sql-server-2008-r2 data-warehouse

Scaling Up Your Data Warehouse with SQL Server 2008 R2中,作者建议使用格式为YYYYMMDD的整数日期键作为事实表的聚簇索引,以帮助优化查询速度。

将关键日期字段转换为日期键的最佳方法是什么?我觉得以下方法可行,但有点草率:

select Replace(CONVERT(varchar,GETDATE(),102),'.','')

显然,我没有使用getdate,而是使用表格中的日期列,该列将在我的聚合中使用。

首先,您如何建议进行此转换?我的想法可以接受吗?

第二,有人使用Date Key作为聚集索引取得了很大的成功吗?

3 个答案:

答案 0 :(得分:10)

ISO long(112)可以解决这个问题:

SELECT CONVERT(INT, CONVERT(VARCHAR(8), GETDATE(), 112))

直接使用ISO 112将getdate()直接转换为int由于某种原因而给出了41008,但是通过VARCHAR似乎可以工作 - 如果我想到更快的演员,我会更新。

编辑:关于int only vs varchar辩论,以下是我的发现(在我的测试装备和生产服务器上可重复)Varchar方法使用较少的CPU时间用于50万个演员但是a整体分数较慢 - 除非你处理数十亿行

,否则可以忽略不计

编辑2 :修改测试用例以清除缓存和不同日期

DBCC FREEPROCCACHE;
DBCC DROPCLEANBUFFERS;
SET STATISTICS TIME ON;
WITH    RawDates ( [Date] )
          AS ( SELECT TOP 500000
                        DATEADD(DAY, N, GETDATE())
               FROM     TALLY
             )
    SELECT  YEAR([Date]) * 10000 + MONTH([Date]) * 100 + DAY([Date])
    FROM    RawDates
SET STATISTICS TIME OFF 

(500000 row(s) affected)

 SQL Server Execution Times:
   CPU time = 218 ms,  elapsed time = 255ms.    
DBCC FREEPROCCACHE;
DBCC DROPCLEANBUFFERS;
SET STATISTICS TIME ON;
WITH    RawDates ( [Date] )
          AS ( SELECT TOP 500000
                        DATEADD(DAY, N, GETDATE())
               FROM     TALLY
             )
    SELECT  CONVERT(INT, CONVERT(VARCHAR(8), [Date], 112))
    FROM    RawDates
SET STATISTICS TIME OFF 

(500000 row(s) affected)

 SQL Server Execution Times:
   CPU time = 266 ms,  elapsed time = 602ms

答案 1 :(得分:4)

您可以使用DATEDIFF函数来获取0之间的天数(即“由0表示的日期”)和您制作DateKey的日期,而不是使用YYYYMMDD格式创建DateKey。对

SELECT DATEDIFF(day,0,GETDATE())

缺点是您无法轻松查看值并确定日期,但您可以使用DATEADD函数计算原始日期(我也看过这个技巧用截断时间部分日期时间。)

SELECT DATEADD(day, 41007, 0)

(注意:41007是我在2012年4月10日运行时DATEDIFF函数的结果。)

答案 2 :(得分:3)

转换为字符串并再次返回可能会非常缓慢。相反,你可以完全处理整数,如下所示:

Select Year(GetDate()) * 10000 + Month(GetDate()) * 100 + Day(GetDate()) 

在我的简短测试中,这比转换为string然后转换为int要快一些。年,月和日函数均返回一个整数,因此性能稍好一些。