如何避免此子查询并创建索引视图?

Posted

技术标签:

【中文标题】如何避免此子查询并创建索引视图?【英文标题】:How to avoid this subquery and create an indexed view? 【发布时间】:2014-09-14 10:05:03 【问题描述】:

我使用 SQL Server 2008。我有下表“预测”。

Forecast_ID | Budget_Code | IAM_ID | Forecast | Timestamp
1           | 00-0001     | 24     | 123.41   | '01-01'2010'  
2           | 00-0001     | 10     | 111.41   | '02-02'2010' //Is Last
3           | 00-0001     | 44     | 457.10   | '02-02'2010' //Is Last
4           | 00-0002     | 258    | 20       | '01-05'2011' //Is Last
5           | 00-0003     | 3      | 215      | '11-12'2013' //Is Last
6           | 00-0003     | 31     | 85.2     | '10-01'2010' 
7           | 00-0003     | 2      | 15       | '10-01'2010' 

我尝试使用每个 Budget_Code 的最后一个“预测”创建一个索引视图,即。 e.具有最高时间戳的预测(每个 Budget_Code 一行或多行)。

所以我做了以下查询:

CREATE VIEW LastForecasts
WITH SCHEMABINDING
AS
    SELECT Forecast_ID, Budget_Code, IAM_ID, Forecast
    FROM dbo.[Plan] p1
    WHERE Timestamp = (
           SELECT MAX(Timestamp) 
           FROM dbo.[Plan] p2 
           WHERE p1.Budget_Code = p2.Budget_Code)
GO
CREATE UNIQUE CLUSTERED INDEX IDX_V1 
    ON LastForecasts (Forecast_ID);
GO

但我有以下错误:

无法在视图“OperationPlanDB.dbo.LastForecasts”上创建索引,因为它包含一个或多个子查询。考虑将视图更改为仅使用联接而不是子查询。或者,考虑不索引此视图。

如何避免此子查询并使用最新预测索引我的视图?

【问题讨论】:

也许我错过了一些东西,但有什么理由不能索引 Timestamp 列(desc 或 asc,没关系)并覆盖其他列(Forecast_ID、Budget_Code、IAM_ID、Forecast) ,然后执行TOP WITH TIESORDER BY @g2server 我不认为TOP WITH TIES 可以工作(但我不是很熟悉),因为每个时间戳可以有一对多行(请参阅预算代码 00-0001我的例子) 好的,我明白了,我错过了分组。在那种情况下,我认为 medhi 的方法会起作用(但更改为 RANK() 并尝试在 Timestamp 上建立索引,用查询替换索引视图 - 如果索引设置正确,性能应该相似)。 【参考方案1】:

您不能在索引视图中使用子查询。我建议使用以下性能更好的查询而不是您的查询:

SELECT *
FROM (
    SELECT Forecast_ID, 
            Budget_Code, 
            Forecast,
            ROW_NUMBER() OVER (PARTITION BY Budet_Code ORDER BY Timestamp DESC) row
    FROM dbo.[Plan] p1
    )z
WHERE Z.row=1

【讨论】:

感谢您的回答,但我忘了说我可以有多个具有相同时间戳的预测,如果时间戳是此 Budget_Code 的最后一个,我需要获取所有预测。顺便说一句,我在示例中添加了另一列 @g2server 确实它适用于 RANK() 但我仍然无法在索引视图中使用它:/ 错误:“无法在视图“dbo.LastForecasts”上创建索引,因为它包含排名或聚合窗口函数。” 这在索引视图中不起作用,对吗?不支持派生表 (z)。

以上是关于如何避免此子查询并创建索引视图?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server里面啥样的视图才能创建索引

ORACLE 创建视图索引序列

oracle视图与索引

是否可以设置 Oak 属性索引并避免重新索引?

mysql中如何建立视图?

MSSQL之八 实现视图与索引