在Scaling Up Your Data Warehouse with SQL Server 2008 R2中,作者建议使用格式为YYYYMMDD的整数日期键作为事实表的聚簇索引,以帮助优化查询速度。
将关键日期字段转换为日期键的最佳方法是什么?我觉得以下方法可行,但有点草率:
select Replace(CONVERT(varchar,GETDATE(),102),'.','')
显然,我没有使用getdate,而是使用表格中的日期列,该列将在我的聚合中使用。
首先,您如何建议进行此转换?我的想法可以接受吗?
第二,有人使用Date Key作为聚集索引取得了很大的成功吗?
答案 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要快一些。年,月和日函数均返回一个整数,因此性能稍好一些。