我有2个表“Vector”和“VectorElement”。向量具有许多元素,因此Vector和VectorElement之间存在外键关系,具有级联删除
Vector有一个字段VectorSize,其中包含VectorElement中相关记录的数量
显然,这个领域是多余的,但它可以优化性能并使我们的查询简单,因为我们对向量中的元素数量感兴趣。
VectorElement上有一个触发器,用于更新Vector中的VectorSize字段。当一个事务中删除或插入许多Vector记录时,此触发器可以工作但速度很慢
当Vector被删除时,级联删除会删除触发器触发的VectorElements。现在触发器确实更新了待删除的Vector记录,这可能会导致一些麻烦,但插件也会发生这种情况。
这是触发器:
CREATE TRIGGER [TFact].[AfterDeleteInsertVectorElement]
ON [TFact].[VectorElement]
AFTER DELETE, INSERT
AS
BEGIN
SET NOCOUNT ON;
WITH cteChangedVectors AS
(
SELECT DISTINCT i.VectorId
FROM inserted i
UNION
SELECT DISTINCT i.VectorId
FROM deleted i
)
UPDATE
TFact.Vector
SET
VectorSize = x.size
FROM
Vector v
JOIN
(SELECT VectorId, COUNT(*) as size FROM TFact.VectorElement GROUP BY VectorId) x
ON v.Id = x.VectorId
JOIN cteChangedVectors chg ON chg.VectorId = v.Id
END
答案 0 :(得分:1)
尝试使用索引视图跟踪VectorElements的总数。
请参阅http://technet.microsoft.com/en-us/library/cc917715.aspx#XSLTsection124121120120
SQL Server知道如何有效地跟踪聚合 - 这比每次触发调用启动一条通用程序代码便宜。
如果您使用的是SQL Server Enterprise,只需创建视图,您的查询将被动态重写以使用它们。
像...一样的东西。
CREATE VIEW VectorSize AS
SELECT VectorId, COUNT(*)
FROM Vector NATURAL JOIN VectorElement
GROUP BY VectorId
GO
CREATE UNIQUE CLUSTERED INDEX VectorSizeInd ON VectorSize( VectorId )
然后,SQL Server将在数据库中保持矢量大小的自动更新“硬拷贝”。
答案 1 :(得分:0)
SQL看起来很复杂。如果您期望大型套装,请单独处理
IF EXISTS (SELECT * FROM DELETED)
UPDATE
V
SET
VectorSize = x.size
FROM
Vector V
JOIN
(SELECT
VectorId, COUNT(*) as size
FROM
DELETED
GROUP BY
VectorId
) x
ON v.Id = x.VectorId
ELSE
UPDATE
V
SET
VectorSize = x.size
FROM
Vector V
JOIN
(SELECT
VectorId, COUNT(*) as size
FROM
INSERTED
GROUP BY
VectorId
) x
ON v.Id = x.VectorId
答案 2 :(得分:0)
这样更好吗?
UPDATE TFact.Vector
SET VectorSize = x.size
FROM Vector v
inner join (
select VectorId, count(*) size
from TFact.VectorElement
where VectorId in (select VectorId from cteChangedVectors)
group by VectorId
)x on x.VectorId = v.Id
如果DB gest很大,还要确保你有TFact.VectorElement.VectorId的索引。
关心GJ
答案 3 :(得分:0)
为什么不从插入表和已删除的表中计算“Delta”值,而不是重新计算子表的总和?
UPDATE
V
SET
VectorSize = VectorSize + Delta
FROM
Vector V
inner join
(select VectorID,SUM(Deltas) as Delta from
(select VectorID,1 as Deltas from inserted union all
select VectorID,-1 from deleted) t
group by VectorID
) u
on
V.VectorID = u.VectorID