2

这是我的场景:

我有一个简单的存储过程,它从表中删除一组特定的行(我们会说大约 30k 行),然后插入大约相同数量的行。这通常只需要几秒钟;但是,该表上有一个触发器,用于监视插入/删除,并尝试模仿另一台服务器上的链接表发生的情况。

由于触发器,这个过程又慢得令人难以置信,并且在这个过程中表也被锁定。所以这是我的两个问题:

  1. 我猜减速的很大一部分是由于事务日志。有没有办法让我在我的存储过程中指定我不希望记录过程中的内容?
  2. 有没有办法让我在整个过程中不锁定表格的情况下执行“删除”和“插入”命令?

谢谢!

编辑- 感谢您的回答;我认为是这种情况(无法执行上述任何一项),但想确定一下。触发器是很久以前创建的,看起来不是很有效,所以看起来我的下一步将是深入了解需要什么以及如何改进它。谢谢!

4

5 回答 5

2

1)不,你也没有做像 TRUNCATE 或 BULK INSERT 这样的最小记录操作

2) 不,否则您将如何防止腐败?

于 2009-01-14T18:26:46.607 回答
1

我不会自动假设性能问题是由于日志记录造成的。事实上,触发器的编写方式很可能会导致您的性能问题。我鼓励您修改原始问题并显示触发器的代码。

于 2009-01-14T18:27:13.983 回答
1

修改数据时不能关闭事务完整性。使用 select * from table (nolock)选择数据时可以忽略锁;但是,您需要非常小心并确保您的应用程序可以处理脏读。

于 2009-01-14T18:28:04.670 回答
1

它对您的触发器没有帮助,但锁定问题的解决方案是小批量执行事务。

代替

DELETE FROM Table WHERE <Condition>

做类似的事情

WHILE EXISTS ( SELECT * FROM table WHERE <condition to delete>)
BEGIN
  SET ROWCOUNT 1000
  DELETE FROM Table WHERE <Condition>
  SET ROWCOUNT 0
END
于 2009-01-14T18:36:15.073 回答
1

您可以暂时禁用触发器,运行您的 proc,然后以更有效的方式执行触发器正在执行的任何操作。

-- disable trigger
ALTER TABLE [Table] DISABLE TRIGGER [Trigger]
GO

-- execute your proc
EXEC spProc
GO

-- do more stuff to clean up / sync with other server
GO

-- enable trigger
ALTER TABLE [Table] ENABLE TRIGGER [Trigger]
GO
于 2009-01-14T18:41:51.600 回答