我有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会重新排序并更新索引。
由于已建立索引的视图,因此,当更新视图中引用的任何实现的对象时,该视图上的关联索引也会被更新。创建索引视图时,这是非常重要的考虑因素。
每个BOL:
在由大量索引视图或较少但非常复杂的索引视图引用的表上执行DML1时,也必须更新那些引用的索引视图。结果,DML查询性能可能会大大降低,或者在某些情况下甚至无法生成查询计划。在这种情况下,请在生产使用前测试DML查询,分析查询计划并调整/简化DML语句。
如UPDATE,DELETE或INSERT操作。
更新dbo.attribute时,您将更新两个索引:pk_attribute和idx_vw_attributevalues_for_entity_entityId。idx_vw_attributevalues_for_entity_entityId使用三列集群键,其中包括entity
NVARCHAR(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] 删除。
我来说两句