小编Ala*_*ain的帖子

实际执行计划中未使用索引视图?

我有一个索引视图的适度用例,它折叠一列并总结一个大表中的所有条目:

CREATE VIEW dbo.Losses_CombinedPortfolio WITH SCHEMABINDING
AS
    SELECT [Category], [Year], 
           SUM(ISNULL(Loss,0)) AS [Loss], COUNT_BIG(*) as [Count]
    FROM dbo.Sub_Portfolio_Losses
    GROUP BY [Category], [Year]
GO
CREATE UNIQUE CLUSTERED INDEX Idx
ON dbo.Losses_CombinedPortfolio([Category], [Year]);
Run Code Online (Sandbox Code Playgroud)

我最初的目标更加雄心勃勃,但索引视图的限制如此之多......我很高兴能够让它发挥作用。

可悲的是,当我尝试对此索引视图进行基本查询时:

SELECT TOP (100) * 
FROM Losses_CombinedPortfolio 
ORDER BY Loss DESC
Run Code Online (Sandbox Code Playgroud)

...查询也很慢,实际执行计划表明它总是回到源表并每次从头开始计算聚合:

实际执行计划

我只能假设这是因为我计算出的“损失”列没有被具体化 - 但这会让我感到惊讶,因为聚集索引创建成功。


请注意,此视图的主要用例是按Loss降序排序,但我无法明确创建包含它的索引:

CREATE UNIQUE CLUSTERED INDEX Idx 
ON dbo.Losses_CombinedPortfolio
    (Category, Loss DESC, [Year]);
Run Code Online (Sandbox Code Playgroud)

我收到错误:

无法在视图 'dbo.Losses_CombinedPortfolio' 上创建索引或统计信息 'Idx',因为关键列 'Loss' 是不精确的、已计算的且未持久化。考虑删除对视图索引或统计键中的列的引用或更改列以使其精确。如果在基表中计算列,请考虑在那里将其标记为 PERSISTED。

我尝试通过将总损失转换为除float(甚至尝试将其截断为bigint)以外的类型来解决“不精确”,但似乎此错误源于用于计算总和的基础类型。

我很困惑 - 我看到其他问题声称他们能够成功地执行聚合,例如sum …

sql-server optimization materialized-view sql-server-2016

6
推荐指数
1
解决办法
227
查看次数