我有以下看法
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
表中有aprx 500 000行,而Hotel
表中有aprx 100 000
答案 0 :(得分:1)
如评论中所述,您可以使用WITH (NOEXPAND)
提示来强制使用索引视图。
这样做时,它表明强制性计划的费用大约是原始计划费用的10%,因此您可能希望以成本为理由进行选择。
但是,编译的工作方式是先扩展视图定义,然后在优化过程中稍后再将其与索引视图匹配,也可能不匹配。对于便宜的计划,优化可能会在没有完成该步骤的情况下结束。
有关更多信息,请参见Paul White's answer here。这也提到了
索引视图匹配在优化阶段0不可用 (交易处理)。
事务处理步骤与至少引用3个表和嵌套循环联接的查询有关,因此完全有可能优化就在那里结束。
如果增加表的大小(尤其是HotelBooking
),并且原始计划变得更加昂贵,则将花费更多时间进行优化,并且索引视图可能最终匹配。
您始终可以使用提示来确定。