复制触发器大大减慢了数据库操作

时间:2009-07-15 16:17:27

标签: sql sql-server-2005 tsql

我们的原始数据库已经为人名命名了第一个,中间一个,最后一个。我们现在创建了名为firstname,middlename和lastname的字段。在我们进行此转换的过程中,我创建了一个触发器,可以在前一个字段接收更新或插入时随时将数据从第一个名称复制到第一个名称,从中间名到中间名,以及从最后一个到最后一个名称。问题是当我们批量上传文件到我们的数据库时,它会减慢一切,并可能导致其他事件超时。

以下是我的代码:

USE [Database]
GO
/****** Object:  Trigger [dbo].[CopyFirstName]    Script Date: 07/15/2009 08:35:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER [dbo].[CopyFirstName]

   ON  [dbo].[Patients]
   AFTER  INSERT,UPDATE
AS 
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

     IF UPDATE([First]) BEGIN
        SET NOCOUNT ON;
declare @ChangedField nvarchar(50);

  select @ChangedField = [First] from inserted 
  update dbo.Patients set FirstName  = @ChangedField where [First]  = @ChangedField


END
end

这可以改进或以其他方式完成吗?

2 个答案:

答案 0 :(得分:5)

一些想法:

  • 如果你有第一个,中间和最后一个触发器,那么我猜你有3个触发器,3个“插入”表扫描和3个更新

  • 您当前的代码不支持多行更新或插入

  • 通过使用“...where [First] = @ChangedField”,如果您可能正在更新多行。假设您输入了“John”或“Hans”。虽然约翰或汉斯是正确的,但你仍在用约翰或汉斯更新每一行。并忽略插入的其他行(请参阅上一点)

选项:

  • 合并为一个触发器
  • 仅更新已更改的行
  • 为旧/新列差异添加过滤器
  • 减少工作(例如,为所有列组合一个语句)

你可以做什么的例子:

ALTER TRIGGER [dbo].[CopyNames]
   ON  [dbo].[Patients]
   AFTER  INSERT,UPDATE
AS 
BEGIN
SET NOCOUNT ON;

IF NOT EXISTS (SELECT * FROM INSERTED)
    RETURN;

IF UPDATE(First) OR UPDATE(Middle) OR UPDATE (Last)
  update
      P
  set
      FirstName  = INS.First,
      Middlename  = INS.Middle,
      LastName  = INS.Last
  FROM
      dbo.Patients P
      JOIN
      INSERTED INS ON P.KeyColumn = INS.KeyColumn
/* optional, try it and see
  WHERE
      P.FirstName <> INS.First OR
      P.Middlename <> INS.Middle OR
      P.LastName <> INS.Last
*/


END

答案 1 :(得分:0)

您可以禁用触发器插入更新一个更新语句中的字段,然后重新启用触发器。