我们正试图通过减少隐式转换来加速我们的一些存储过程。我们试图弄清楚的一个问题是如何修复几个与此类似的索引视图:
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
保留这些列类型的最佳方法是什么?还是“最佳实践”?
答案 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的较少“高级”版本上实际使用基础索引视图。