5

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

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

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

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

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

其次,有没有人使用日期键作为聚集索引取得了很大的成功?

4

3 回答 3

10

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

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

出于某种原因,使用 ISO 112 将 getdate() 直接转换为 int 会得到 41008,但通过 VARCHAR 似乎可行 - 如果我想到更快的转换,我会更新。

编辑:关于仅 int 与 varchar 的辩论,这是我的发现(可在我的测试台和生产服务器上重复) Varchar 方法使用更少的 cpu 时间来进行 50 万次投射,但总体速度要慢一点 - 可以忽略不计,除非你处理数十亿行

编辑 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
于 2012-04-10T15:33:49.497 回答
4

转换为字符串然后再转换回来可能会非常慢。相反,您可以完全处理整数,如下所示:

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

在我的简短测试中,这比转换为字符串然后转换为 int 稍快。年月日函数各返回一个整数,所以性能稍好一些。

于 2012-04-10T15:56:35.267 回答
4

除了使用 YYYYMMDD 格式创建 DateKey 之外,您还可以使用DATEDIFF函数来获取 0(即“由 0 表示的日期”)和您为其创建 DateKey 的日期之间的天数。

SELECT DATEDIFF(day,0,GETDATE())

缺点是您不能轻松查看值并确定日期,但您可以使用DATEADD函数来计算原始日期(我还看到这个技巧用于截断日期时间的时间部分)。

SELECT DATEADD(day, 41007, 0)

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

于 2012-04-10T16:15:04.063 回答