【问题标题】:Poor SQL Server Update Trigger PerformanceSQL Server 更新触发器性能不佳
【发布时间】:2013-11-20 21:15:51
【问题描述】:

我正在使用 SSIS 使用 SQL Server 2008 R2 更新表中的 13000 行,该表上有一个更新触发器,没有触发器更新需要 1 小时。

我原本预计使用触发器需要两倍的时间(

表:

CREATE TABLE [Dim].[Company]
(
[CompanyKey] INT NOT NULL IDENTITY , 
[Name] nCHAR(255) NOT NULL, 
[City] nCHAR(100) NOT NULL, 
[Country] nCHAR(100) NOT NULL, 
[PostCode] nCHAR(20) NOT NULL, 
[Continent] nCHAR(100) NOT NULL, 
[EcconomicRegion] nCHAR(50) NOT NULL, 
[ErdfAreaType] nCHAR(10) NOT NULL, 
[PostCodeLong] nCHAR(10) NOT NULL, 
[PostCodeLat] nCHAR(10) NOT NULL, 
[Type] nCHAR(50) NOT NULL, 
[NumEmployees] int NOT NULL, 
[AnnualRevenue] MONEY NOT NULL, 
[BalanceSheetTotal] MONEY NOT NULL, 
[OwnershipType] nCHAR(50) NOT NULL, 
[MembershipType] nCHAR(50) NOT NULL, 
[AccountManagerKey] INT NOT NULL 

CONSTRAINT [PK_Company] PRIMARY KEY CLUSTERED ([CompanyKey] asc)
)
GO
CREATE INDEX [IX_Company_NameCityPostcode] ON [Dim].[Company] ([Name], [City], [PostCode])
GO
CREATE INDEX [IX_Company_Name] ON [Dim].[Company] ([Name])
GO
CREATE INDEX [IX_Company_City] ON [Dim].[Company] ([City])
GO
CREATE INDEX [IX_Company_Postcode] ON [Dim].[Company] ([PostCode])

触发器:

CREATE TRIGGER [Dim].[Company_Update] ON [Dim].[Company] FOR UPDATE 
AS BEGIN SET NOCOUNT ON update [dim].[company] set ModifiedOn = GETDATE() END

更新执行计划:不确定它是否可见,但它显示执行 1,操作员成本 0.040004 (92%)

触发器更新执行计划:不确定它是否可见,但它显示执行 1,操作员成本 22.300197 (97%)

回答: 基于 Emmad Kareem 的回答和这个 SO 问题 - trigger updates entire table even on single-row update

我将触发器更改为:

CREATE TRIGGER [Dim].[Company_Update] ON [Dim].[Company] FOR UPDATE AS BEGIN 
SET NOCOUNT ON 
update [dim].[company] set ModifiedOn = GETDATE() 
from [Dim].[Company] bf
inner join inserted i on i.CompanyKey = bf.CompanyKey
END
GO

更新现在按预期执行

【问题讨论】:

    标签: performance sql-server-2008 triggers ssis


    【解决方案1】:

    更新触发器 SQL 没有 WHERE 子句来指定要更新的特定行。

    【讨论】:

    • 我该怎么做?我假设每次更新的行都会调用一次触发器,并且它知道是哪一行。
    • @Stuart,抱歉我不在。真高兴你做到了。只是想知道第一次插入行时列的内容。我认为它将为空。小心点。
    • 它有一个默认约束 = GETDATE()
    【解决方案2】:

    您缺少触发器上的 where 子句,因此基本上它每次都会更新表中的每一行。试试这样的:

    CREATE TRIGGER [Dim].[Company_Update] 
    ON [Dim].[Company] FOR UPDATE 
     AS
     UPDATE [dim].[company]
      SET ModifiedOn = GETDATE()
      WHERE CompanyKey IN (SELECT DISTINCT CompanyKey FROM Inserted)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-03
      • 1970-01-01
      • 1970-01-01
      • 2014-03-26
      • 1970-01-01
      • 1970-01-01
      • 2015-01-20
      • 2016-11-03
      相关资源
      最近更新 更多