为什么在更新索引中未包含的视图值时,视图上的聚集索引会被更新并重新排序?

噻菌灵

我有table属性:

attributeId     INT IDENTITY,
entity          NVARCHAR(150) NOT NULL,
rank            INT NOT NULL,
label           NVARCHAR(500) NOT NULL,
CONSTRAINT pk_attribute PRIMARY KEY CLUSTERED (attributeId)

该表的attributeValues:

attributeId         INT NOT NULL,
entityId            INT NOT NULL,
value               SQL_VARIANT NOT NULL,
CONSTRAINT pk_attributeValues PRIMARY KEY CLUSTERED (attributeId, entityId),

所以我提出了一个观点:

CREATE VIEW dbo.vw_attributevalues
WITH SCHEMABINDING, VIEW_METADATA
AS
    SELECT  a.entity, av.entityId, a.attributeId, av.value,
            a.rank, a.label,
    FROM    dbo.attribute a
    JOIN    dbo.attributeValue v
            ON a.attributeId = v.attributeId
GO

CREATE UNIQUE CLUSTERED INDEX idx_vw_attributevalues_for_entity_entityId
    ON dbo.vw_attributevalues (entity, entityId, attributeId) WITH (DATA_COMPRESSION = PAGE);
GO

当我更新等级(它不在索引中)时,它将更新索引并对其重新排序:

UPDATE dbo.attribute
SET rank = 25000
WHERE attributeId = 100011;

执行计划

这部分非常昂贵。我不明白为什么sql server会重新排序并更新索引。

艾伦·伯斯坦(Alan Burstein)

由于已建立索引的视图,因此,当更新视图中引用的任何实现的对象时,该视图上的关联索引也会被更新。创建索引视图时,这是非常重要的考虑因素。

每个BOL

在由大量索引视图或较少但非常复杂的索引视图引用的表上执行DML1时,也必须更新那些引用的索引视图。结果,DML查询性能可能会大大降低,或者在某些情况下甚至无法生成查询计划。在这种情况下,请在生产使用前测试DML查询,分析查询计划并调整/简化DML语句。

如UPDATE,DELETE或INSERT操作。

更新dbo.attribute时,您将更新两个索引:pk_attribute和idx_vw_attributevalues_for_entity_entityId。idx_vw_attributevalues_for_entity_entityId使用三列集群键,其中包括entityNVARCHAR(150)列。根据dbo.attribute和dbo.attributeValue中的记录数,是昂贵的更新。

请注意以下DDL和执行计划:

-- sample data
CREATE TABLE dbo.a(c INT PRIMARY KEY CLUSTERED);
CREATE TABLE dbo.b(c INT PRIMARY KEY CLUSTERED);
INSERT dbo.a(c) VALUES(1),(2),(3);
INSERT dbo.b(c) VALUES(1),(2),(5);
GO

-- Sample indexed view
CREATE VIEW dbo.vw_ab
WITH SCHEMABINDING AS
SELECT ac = a.c, bc = b.c
FROM   dbo.a
JOIN   dbo.b ON a.c < b.c;
GO
CREATE UNIQUE CLUSTERED INDEX uq_dbo_vw_ab ON dbo.vw_ab(ac, bc);
GO

在这里,我们将dbo.a和dbo.b加入其中,然后添加一个索引视图。请注意执行计划,在更新dbo.a或dbo.b时,我将更新每个表上的聚集索引以及视图上的索引。注意插入和相关的执行计划:

-- Inserts:
INSERT dbo.a(c) VALUES(20);
INSERT dbo.b(c) VALUES(50);

执行计划:

在此处输入图片说明

为了更好地理解为什么更新/插入/删除操作成本高昂,请先删除不同的索引,添加/修改数据,然后比较使用和不使用索引的影响,然后开始进行测试。我怀疑NVARCHAR(150)列是在这里杀死您的原因。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么聚集索引是对字段更新的更新,而该字段未包含在该索引中(Ms SQL)?

熊猫更新数据框视图上的索引

索引视图上的SQL Server列存储聚集索引

索引视图何时更新?

为什么在指令的视图中我的值未更新

为什么在视图未更新时使用@State var

视图模型更新时视图未更新

为什么索引视图实现了?

模型中的值未更新到视图

遍历这个包含数组作为值的对象并组合所有值,对它们进行排序,重新索引和更新值

进行集成测试时强制Couchbase更新视图索引

在SQL Server中的视图中创建唯一的聚集索引时出错

当视图在数据库上更新时,休眠搜索不更新视图的索引

值不会在视图上更新

在索引视图上按 id 排序的最佳方法

在Mendix中更新实体时,数据视图未更新

合并数组,排序值,删除重复项并重新索引

在表或视图上设置索引?

从索引视图调用更新方法

如何刷新表视图以更新索引?

当where子句列中没有聚集索引时,并行更新会导致死锁

在列表视图中更新视图的值时,适配器未更新

React Hook [useState]:更新状态并重新渲染视图

为什么我们不能更新定义中包含DISTINCT子句的视图?

当我在索引视图上将列转换为NVarchar时,索引默认为允许空值'YES'

如何在“索引”视图上列出嵌套的属性值?

在视图上创建全文索引时出现问题

在我重新加载目标C中的表视图时,为什么选择值会取消选择

为什么Query Optimizer完全忽略索引视图索引?