sql - 使用 NOEXPAND 更新索引视图
问题描述
假设我有一个 table T
,并且我有一个索引视图V
:
CREATE TABLE dbo.T (id int PRIMARY KEY, b bit NOT NULL, txt varchar(20));
GO
CREATE VIEW dbo.V
WITH SCHEMABINDING AS
SELECT T.Id, T.txt
FROM dbo.T AS T
WHERE T.b = 1;
GO
CREATE UNIQUE CLUSTERED INDEX idx_V ON dbo.V (Id);
在这个简单的例子中,它基本上只是一个过滤索引,但它也可以有连接等。
我现在想在T
where中选择一些行,这里b = 1
的过滤视图非常有用,而且我在 Standard 所以必须使用NOEXPAND
(或者它对于视图匹配来说太复杂了):
SELECT Id, txt
FROM V WITH (NOEXPAND);
现在我想将这些行更新为某个值。该视图符合可更新的条件,因此我可以这样做:
UPDATE V
SET txt = 'Foo';
这不使用索引视图来查找要更新的行,即使它需要它们来实际更新视图。我想做的是像普通表索引一样使用视图,并确定要从中更新的行,将它们传递给 Clustered Index Update on T
,然后是视图上的 Update。所以我试试这个:
UPDATE V WITH (NOEXPAND)
SET txt = 'Foo';
这失败了"Hint 'noexpand' on object 'V' is invalid."
我知道我可以通过这样的查询来解决它:
UPDATE T
SET txt = 'Foo'
FROM T
JOIN V WITH (NOEXPAND) ON V.Id = T.Id;
但这意味着额外的 Seek。不仅如此,它还在随后的索引视图更新中添加了一个过滤器,以检查行是否与视图匹配(连接视图需要评估连接),显然,它们必须与视图匹配。
有没有办法让它以我想要的方式工作?
更新:
将视图放在FROM
子句中,甚至放在派生表、CTE 或其他视图中都无济于事。一旦它查看解析器它正在用于更新,它就会失败。
在Table Hints、Indexed View或Updatable Views文档中没有任何指示不NOEXPAND
应该工作。该声明的文档特别提到某些表格提示是不允许的,但只是被排除在外(最近更新为添加但没有解释)UPDATE
NOLOCK
READUNCOMMITTED
NOEXPAND
解决方案
推荐阅读
- ruby-on-rails - 找不到没有身份证的假期
- react-native - 当用户按下回车键时,如何在 TextInput 上触发函数?
- google-colaboratory - 我的代码有什么问题,我尝试了很多方法,但我不断得到这个: TypeError: must be str, not int
- r - 为什么我在应用于向量和 xts 对象时在 ks.boot 输出中得到不同的结果?
- python - 如何从表中选择熊猫系列中的值?
- python - 来自不同文件的 Python 线程函数
- python - 向下滚动网页内的框?硒蟒
- angular - 如何使用 Render2 ( Angular ) 选择文本
- java - 我正在尝试创建一个搜索查询“我的用户相对于当前在线用户的距离”。我对所有人都有 lat 和 Long 值
- angular - 如何删除 Angular 表单组中的特定错误