触发器性能 - 1 个或 2 个触发器?

Art*_*yan 2 trigger sql-server sql-server-2014

我有一个关于触发器性能的问题。

CREATE TABLE [dbo].[_test](
[ID] [INT] IDENTITY(1,1) NOT NULL,
[Date] [DATETIME] NULL,
[DateYearID] [INT] NULL,
[DateQuarterID] [INT] NULL,
[Date1] [DATETIME] NULL,
[Date1YearID] [INT] NULL,
[Date1QuarterID] [INT] NULL)
Run Code Online (Sandbox Code Playgroud)

现在我想要触发器,如果​​我更新 Date 列(或插入新行),必须更新 DateYearID 和 DateQuarterID 列,如果我更新 Date1 列(或插入新行),则必须更新 Date1YearID 和 Date1QuarterID 列。有什么更好的,有一个触发器,比如

IF UPDATE(DATE)
   UPDATE _test SET DateYearID = ... , DateQuarterID = ...
IF UPDATE (DATE1)
   UPDATE _test SET Date1YearID = ... , Date1QuarterID = ...
Run Code Online (Sandbox Code Playgroud)

或者有两个不同的触发器,第一个更新 DateYearID,DateQuarterID 列,第二个更新 DateYear1ID,DateQuarter1ID 列。

我正在使用 SQL Server 2014。

非常感谢您的帮助。

Aar*_*and 6

我建议使用单个触发器,通过插入和/或基表进行一次传递,并且只需更新受影响的任何行的所有四个值。我之前已经证明,避免更新其他列值已更改的行中的列是不值得的,并且从两个不同的触发器更新同一行两次会更慢

IF UPDATE(DATE) OR UPDATE(DATE1)
BEGIN
  UPDATE t 
    SET DateYearID   = ...,
        DateQuarterID  = ...,
        Date1YearID    = ...,
        Date1QuarterID = ...
  FROM dbo._test AS t
  INNER JOIN inserted AS i
  ON t.ID = i.ID;
END     
Run Code Online (Sandbox Code Playgroud)

(另外,顺便说一句,请注意它UPDATE()告诉您在更新语句中引用了该列,但它不能保证该值已更改。)

是的,我同意Gianluca 的评论:根据这四列的计算方式,您可能根本不需要触发器。您甚至可能不需要计算列 - 简单的计算(如DATEPART(YEAR,Date1))通常最好在查询时完成,并且仅在您需要时进行。存储冗余数据被高估了——在几乎所有系统中,I/O 和内存比 CPU 重要得多,即使使用今天的 SSD 和 PCIe 闪存驱动器......