【问题标题】:Performance choice: DML vs DDL trigger性能选择:DML 与 DDL 触发器
【发布时间】:2021-08-07 09:27:11
【问题描述】:

我有一个表 [A],其中包含一些列和一个 PK。每次在 [A] 上执行 update 时,我都想将更新的行的旧值和新值保留在另一个表 [Alog] 中。所以我有一些触发器可以做到这一点。

为了只保留更新的列,我在更新触发器上使用columns_updated()。但是为了获得更好的性能,我应该检查什么?

  1. 一种逻辑是进行位“解码”并将其与 sys.columns.column_id 进行比较。我在这个解决方案中不喜欢的是在每行更新时读取 sys 架构

  2. 另一个逻辑是在代码中为每一列放置位掩码文字(例如:

    column4 = @columns_updated & 0x08 > 0 时的情况,然后 column4 结束 ) 这存在列可能会更改其 column_id 的危险,因此我必须在数据库上创建一个 DDL 触发器,如果​​表被更改,它将重新创建触发器代码。我不喜欢这个解决方案的地方是数据库触发器在每个 ddl 语句上都会触发。

读取每个表行上的 sys.columns 与触发 ddl 触发器相比如何?

【问题讨论】:

  • 是的。我可能会将其合并到代码中,但这是另一回事。
  • columns_updated() 不像大多数人期望的那样工作.....
  • 如果目标是保留历史记录,请使用临时表。它更简单
  • 我们没有 sql16+ 的奢侈——只有功能,它必须在 2012 上工作

标签: sql-server tsql triggers ddl


【解决方案1】:

SQL Server 中的触发器很慢。

您可以使用以下代码:

Update [A]
Set [COLUMN_1] = NEW_VALUE
OUTPUT 
--These are the columns with the old value.
deleted.[COLUMN_1],deleted.[COLUMN_2],deleted.[COLUMN_3],
-- These are the columns with the new value.
--> inserted.[COLUMN_1],inserted.[COLUMN_2],inserted.[COLUMN_3]
INTO [B]
Where [COLUMN_1]=OLD_VALUE

【讨论】:

  • 我无法控制原始语句,它们可以由多种来源执行,例如临时查询、过程和应用程序。
  • “SQL Server 中的触发器很慢” - 该语句不正确。触发器可能比约束强制执行的操作慢,但缓慢的触发器是由没有经验的人创建的,在其中执行不适当或昂贵的操作。
猜你喜欢
  • 2019-07-26
  • 1970-01-01
  • 2015-01-10
  • 2010-12-28
  • 2023-03-28
  • 1970-01-01
  • 2020-02-06
  • 2012-02-08
  • 2014-02-12
相关资源
最近更新 更多