【问题标题】:SQL Insert/Update/Delete Trigger EfficiencySQL 插入/更新/删除触发器效率
【发布时间】:2012-09-19 16:55:31
【问题描述】:

在我们的数据库级应用程序中,我在 Billing 和 Billing_History 架构中有一个名为 Installments 的表。

显示的触发器位于计费模式的分期付款表中。

每次在计费模式中插入/更新记录时,它也会写入历史文件。

如果记录从计费表中删除,则将其写入历史记录表,并带有“已删除”指示符 = true。

我认为随着更多记录的添加,“如果不存在(从插入中选择 *)正在扼杀我的表现。

有没有更高效的方法是写这个触发器?

Create TRIGGER [Billing].[Installments_InsertDeleteUpdate_History]
ON [Billing].[Installments]
AFTER INSERT, DELETE, UPDATE
AS BEGIN
Insert Into Billing_History.Installments
    Select *, GetDate(), 0 From Inserted

If Not Exists (Select * From Inserted)
    Insert Into Billing_History.Installments
        Select *, GetDate(), 1 From Deleted

SET NOCOUNT ON;

-- Insert statements for trigger here

结束

【问题讨论】:

  • 建议您为正在使用的 RDBMS 添加标签。
  • If Not Exists (Select * From Inserted) 不会影响您的性能,但您可以将其替换为 IF @@ROWCOUNT > 0 检查相同的语义。
  • 在插入中选择 * 是一种极差的做法。
  • 建议用大锤子破坏扳机并使用存储的触发。
  • @HABO - getdate() 是一个runtime constant,所以这里的每个语句只会被评估一次,因为在这种情况下两个代码分支是互斥的,我看不到这个问题。

标签: sql sql-server triggers


【解决方案1】:

我建议您使用的触发器表单是性能最好的,因为它是必需的任务。真的没有比这更好的方法来达到同样的审计结果了。

这里的答案是 Creating audit triggers in SQL Server,这里是 long discussion,关于审计解决方案的性能。

您的情况略有不同,因为您实际上不希望在 UPDATE 情况下删除(原始)表,因此不希望使用 IF。

【讨论】:

  • 感谢所有 cmets。在这一点上,我认为没有足够令人信服的证据来更改/删除触发器。我将寻找其他地方以获得性能提升。
【解决方案2】:

为 INSERT 和 UPDATE 创建一个触发器,为 DELETE 创建第二个触发器。这样您就不必使用 IF 语句和慢查询来检查记录的位置。

从设计的角度来看,看看您是否可以消除触发器。他们一团糟。

【讨论】:

  • IF EXISTS(...) 不是一个慢查询。如果 OP 遇到性能问题,我建议他们在该声明之外寻找其他地方。
  • @MartinSmith 我认为你是对的。话虽如此,使用多个触发器来消除不必要的 IF 仍然是有意义的,IMO。
【解决方案3】:

你可以做这个简单的改变:

Create TRIGGER [Billing].[Installments_InsertDeleteUpdate_History]
ON [Billing].[Installments]
AFTER INSERT, DELETE, UPDATE
AS BEGIN

If Not Exists (Select * From Inserted)
    Insert Into Billing_History.Installments
        Select *, GetDate(), 1 From Deleted
ELSE
    Insert Into Billing_History.Installments
        Select *, GetDate(), 0 From Inserted

SET NOCOUNT ON;

-- Insert statements for trigger here

哪个逻辑上更有效,但它是否物理性能更高是一个悬而未决的问题。如果它真的更快,那肯定不会快很多。

【讨论】:

    猜你喜欢
    • 2011-11-25
    • 2011-05-05
    • 2010-12-17
    • 1970-01-01
    • 2011-02-27
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 2013-07-01
    相关资源
    最近更新 更多