索引视图强制非最佳列类型

时间:2012-03-15 22:26:31

标签: sql-server sql-server-2005

我们正试图通过减少隐式转换来加速我们的一些存储过程。我们试图弄清楚的一个问题是如何修复几个与此类似的索引视图:

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

返回:

  

无法创建聚集索引'ix_indexName'   查看'x.dbo.vw_viewName'因为   选择视图列表包含聚合结果的表达式   功能或分组列。考虑删除结果上的表达式   选择列表中的聚合函数或分组列。

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

的效率

保留这些列类型的最佳方法是什么?还是“最佳实践”?

2 个答案:

答案 0 :(得分:2)

我可能会尝试将派生(实际)“BillableDollars”列添加到时间表中并应用转换:

CONVERT(MONEY,(TimeUnit*BillingRate))

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

我相信这样可以让您在计算出的可结算资金总和时获得索引视图。

我希望你在view数据类型中获得比表数据类型更精确的原因是,一堆精度为9的数字的总和加起来需要一个数字精度大于9。

答案 1 :(得分: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的较少“高级”版本上实际使用基础索引视图。