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

时间:2019-02-18 21:14:55

标签: sql sql-server sql-server-2017 clustered-index indexed-view

我有以下看法

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时,我希望看到一个聚集索引扫描,但是我得到了

enter image description here

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

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

编辑1

使用WHERE子句运行查询也无济于事。

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

enter image description here

编辑2

SELECT HBK_ID
FROM web.vGridHotelBooking
WHERE HBK_ID = 1801151518187788

enter image description here

编辑3

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

enter image description here

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

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

enter image description here

那么问题是-为什么?我是否需要担心这一点。 因为CustomerOfferBundle表中有aprx 500 000行,而Hotel表中有aprx 100 000

编辑5 enter image description here

1 个答案:

答案 0 :(得分:1)

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

这样做时,它表明强制性计划的费用大约是原始计划费用的10%,因此您可能希望以成本为理由进行选择。

但是,编译的工作方式是先扩展视图定义,然后在优化过程中稍后再将其与索引视图匹配,也可能不匹配。对于便宜的计划,优化可能会在没有完成该步骤的情况下结束。

有关更多信息,请参见Paul White's answer here。这也提到了

  

索引视图匹配在优化阶段0不可用   (交易处理)。

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

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

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