2012-03-15 58 views
1

我们试图通过减少隐式转换来加速我们的一些存储过程。其中一个我们正在试图找出这些问题是如何解决类似这样的几个索引视图:索引视图强制非最佳列类型

Time.UserID is INT
Time.TimeUnit is DECIMAL(9,2)
Time.BillingRate is MONEY

Select 
    UserID, 
    SUM(TimeUnit) as Hours, 
    SUM(TimeUnit*BillingRate) as BillableDollars 
FROM 
    Time 
GROUP BY 
    UserID 

给我们列一个观点:

UserID(int, null) 
Hours(decimal(38,2), null) 
BillableDollars(decimal(38,6), null) 

我们希望有Hours(decimal(9,2),null)BillableDollars(money,null)

CAST(SUM(TimeUnit*BillingRate) AS MONEY) as BillableDollars

返回:

,因为该视图的 选择列表中包含的合计结果的表达式不能创建 视图“x.dbo.vw_viewName”聚集索引“ix_indexName” 函数或分组列。考虑从选择列表中删除对 聚合函数或分组列的结果的表达式。

我们担心的SUM(CAST(TimeUnit*BillingRate AS MONEY)) as BillableDollars

效率什么是保存这些列类型的最佳方式还是有“最佳实践”?

+1

你试过'SUM(CAST)'的表现吗?您是否还将'MONEY'与更实用的数据类型(例如'DECIMAL(9,2)')恕我直言对比? – 2012-03-15 22:36:37

回答

2

我可能会尝试增加派生(现实化)“BillableDollars”栏目与转换的时间表应用:

CONVERT(MONEY,(TimeUnit*BillingRate)) 

我用钱,但当然,转换可能是任何数据类型最有效地满足您的需求。

我相信这样可以让您在计算出的计费金额上累加索引视图。

我认为你在视图数据类型中获得的精度比表数据类型中的精度要高的原因是精度为9的一串数字的总和加起来就是需要的数字精度大于9

0

只是包装你的索引视图中的第二个“铸造”鉴于这样的

CREATE VIEW MyView 
AS 
SELECT CAST(UserID AS INT)    AS UserID 
     , CAST(TimeUnit AS DECIMAL(9,2)) AS TimeUnit 
     , CAST(BillingRate AS MONEY)  AS BillingRate 
FROM MyViewIndexed WITH (NOEXPAND) 

作为奖励,你可以包括NOEXPAND暗示这样的底层索引视图是由查询优化器实际使用的更少的“高级”版本的MSSQL。