我们在一个相当大的数据库中有很多一对一的关系。一位同事创建了一个视图,将所有这些信息导入一个区域,以便在我们的.NET项目中用作单个对象。
视图具有插入,更新和删除触发器,这些触发器都运行良好,唯一的问题是在更新期间,需要约7秒才能完成,这太长了。由于数据库索引非常好(尽管视图不是),我相信视图的执行方式就是问题
更新触发器的结构如下:
update table1 set col1 = i.col1, col2 = i.col2 .....
from inserted i
inner join table1 t1 on i.id = t1.id
update table2 set col1 = i.t2_col1, col2 = i.t2_col2......
from inserted i
inner join table2 t2 on i.id = t2.t1Id
if @@rowcount = 0 begin
insert table2 (t1Id, col1, col2....)
select i.t1Id, i.t2_col1, i.t2_col2..... from inserted i
end
/* There are an additional 9 update .... if @@rowcount = 0 insert statements */
所以我的理解是,无论哪个属性更新,所有更新语句都会被执行,从而导致性能问题。
我正在重新考虑这样一个事实:我们将不得不重新编写数据访问层以摆脱这种观点,但我想我已经问过是否有任何基于SQL的建议如何加速这触发了
非常感谢任何帮助
答案 0 :(得分:1)
在不知道你在做什么的情况下很难说。我想你可以在那些更新语句中添加一些where子句,因此更新只在某些条件下运行。您还可以将更新语句包装在某些if语句中,并检查插入的记录保证运行更新。您还可以将视图编入索引以帮助加快速度。
答案 1 :(得分:1)
你说的地方:
无论获得哪个属性 更新,所有更新语句 正在执行
在sqlserver触发器中,您可以执行类似
的操作IF UPDATE(Col1)
BEGIN
-- do col1 specific updates
END
请参阅创建触发器文档:http://msdn.microsoft.com/en-us/library/ms189799%28v=SQL.90%29.aspx
另外,当您说“索引良好”时请注意索引会加快查询速度但会降低更新速度
答案 2 :(得分:0)
我有时发现,如果你“向SQL Server指出明显的”它可以表现得更好。也就是说,如果你告诉它只做更新,如果有什么东西需要实际改变。例如,你有:
update t1 set col1 = i.col1, col2 = i.col2 .....
from inserted i
inner join table1 t1 on i.id = t1.id
您可以添加where条件:
where t1.col1 <> i.col1 or t1.col2 <> i.col2 ...
(假设所有列都不可为空 - 否则您需要更多检查)。如果你从中受益,可能值得一看。
如果您有可为空的列,则对于每个此类列,您需要执行3次检查,如下所示:
where
(t1.col1 <> i.col1 or (t1.col1 is null and i.col1 is not null) or (t1.col1 is not null and i.col1 is null)) or
(t1.col2 <> i.col2 or (t1.col2 is null and i.col2 is not null) or (t1.col2 is not null and i.col2 is null))
答案 3 :(得分:0)
派对有点晚了,但我已经(很难)了解到inserted
和deleted
伪表是奇怪的野兽;特别是当涉及的数据量增加时。
由于您无法对它们进行索引或向其添加统计信息(AFAIK),因此查询计划在处理其中的信息时通常会使用非最佳方法。
有时它实际上有助于将那些伪表中的相关数据提取到#temp-tables中并从那里开始工作。因为在这种情况下看起来inserted
字段在id
字段上被反复使用,所以从{{ - table-table开始工作可能是有益的,该临时表具有{{1}上的索引1}} field。