在视图上创建聚簇索引后查询视图仍然会产生相同的查询计划

Querying a view after creating a clustered index on it still yields the same query plan

我有以下看法

SET QUOTED_IDENTIFIER ON
SET ANSI_NULLS ON
GO

ALTER VIEW web.vGridHotelBooking
WITH SCHEMABINDING
AS
    SELECT 
        HBK_ID,
        COF_ID,
        COF_CST_ID,
        HTL_Name,
        COF_Data
    FROM 
        web.HotelBooking
    INNER JOIN 
        web.CustomerOfferBundle ON COF_ID = HBK_COF_ID
    INNER JOIN 
        web.Hotel ON COF_HTL_ID = HTL_ID;
GO

CREATE UNIQUE CLUSTERED INDEX [CLI_vGridHotelBooking__HBK_ID] 
ON [web].[vGridHotelBooking] ([HBK_ID]) ON [PRIMARY]
GO

当我执行语句 SELECT * FROM web.vGridHotelBooking 时,我希望看到单个聚簇索引扫描,但我却得到了这个

这与我直接执行 SELECT 语句时得到的计划相同。

我在这里做错了什么?我已经多次使用物化视图,以前没有遇到过这个问题。

编辑 1

运行 带有 WHERE 子句的查询也无济于事。

SELECT COF_ID
FROM web.vGridHotelBooking
WHERE COF_ID = '06A41DB5-8F14-4E6C-9084-3009E0626DAA';

编辑 2

SELECT HBK_ID
FROM web.vGridHotelBooking
WHERE HBK_ID = 1801151518187788

编辑 3

SELECT HBK_ID
FROM web.vGridHotelBooking WITH (INDEX(CLI_vGridHotelBooking__HBK_ID))
WHERE HBK_ID = 1801151518187788;

编辑 4 运行 这次带有 NOEXPAND 的查询产生了正确的计划。

SELECT *
FROM web.vGridHotelBooking WITH (NOEXPAND)
WHERE HBK_ID = 1801151518187788;

那么问题是 - 为什么会这样?我需要担心这个吗? 因为 CustomerOfferBundle table 中有 aprx 500 000 行,而 Hotel table aprx 100 000

编辑 5

如评论中所述,您可以使用 WITH (NOEXPAND) 提示强制使用索引视图。

当您这样做时,它表明强制计划的成本估计约为原始计划成本的 10%,因此您可能希望根据成本原因选择此计划。

然而,编译的工作方式是首先扩展视图定义,然后在优化过程的后期可能会或可能不会匹配回索引视图。对于便宜的计划,优化可能会在没有到达那一步的情况下结束。

有关详细信息,请参阅 Paul White's answer here。这也提到

indexed view matching is not available in optimization phase 0 (transaction processing).

事务处理步骤与引用至少 3 个表和嵌套循环连接的查询有关,因此您完全有可能优化到此结束。

如果您增加表的大小(尤其是 HotelBooking)并且原始计划变得更加昂贵,将花费更多时间进行优化,索引视图可能最终会匹配。

您始终可以使用提示来确定。