Увеличение производительности триггера на SQL сервере - PullRequest
0 голосов
/ 14 апреля 2020

Я не эксперт по базам данных, но мне нужна некоторая помощь, чтобы убедиться, что триггер, который мы используем для отслеживания обновления таблицы, является лучшим способом справиться с нашей ситуацией и работает так, как должен. После загрузки триггера мы заметили некоторую медленную производительность в реальной бизнес-системе (на стороне пользователя).

Справочная информация: мы пытаемся зафиксировать дату / время транзакции, которая происходит, чтобы на нее можно было ссылаться на портале клиента для нашего веб-сайта.

Теория: триггер отслеживает обновление столбца до 'PI' и, если это происходит, записывает данные в таблицу, предоставляя некоторую основную c информацию из 2 других таблиц, которые связанные с обновлением.

Столбцы таблицы 1

RH.kbranch, RH.kordnum, RH.kcustnum, RH.custsnum, RH.[program]

Столбцы таблицы 2

RD.kbranch, RD.kordnum, RD.kpart

Столбцы таблицы 3 (к которым прикреплен триггер)

EQ.kequipnum, EQ.eqpstatus

Триггер

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER [dbo].[PICKUPTrigger] 
ON [TEST].[dbo].[equip]
FOR UPDATE
AS  
    IF (SELECT eqpstatus FROM inserted) = 'PI'
    BEGIN
        SET NOCOUNT ON

        INSERT INTO [Workfiles].[dbo].[PickupAudit] ([HHBranch],[HHOrder],[HHCustomer], [HHShipTo], [EquipID], [EQStatus], [PickupNo], [StatusDate])
            SELECT 
                RH.kbranch, RH.kordnum, RH.kcustnum, RH.custsnum, 
                RD.kpart, EQ.eqpstatus, RH.[program], GETDATE()
            FROM 
                TEST.dbo.renthead RH
            JOIN 
                TEST.dbo.rentdetl RD ON RH.kbranch = RD.kbranch 
                                     AND RH.kordnum = RD.kordnum 
                                     AND RH.program NOT LIKE 'OPSS%'
            JOIN 
                TEST.dbo.equip EQ ON EQ.kequipnum = RD.kpart
            WHERE 
                RD.kpart = (SELECT kequipnum FROM inserted);
END

Триггер работает, но, похоже, вызывает проблемы и замедляет реальное взаимодействие с пользователем. Мы ценим любую помощь в настройке того, что мы сделали, и если у вас есть какие-либо вопросы, не стесняйтесь спрашивать. Спасибо.

Ответы [ 2 ]

0 голосов
/ 14 апреля 2020

Замедление вызвано операторами объединения, так как я думаю, что вы объединяете тяжелые таблицы с данными или таблицами под нагрузкой, иногда во время операции триггера

Решением для повышения производительности является создание «индексированного представления» не просто «просмотр», а использование его в триггере, и вы увидите, как резко повлияет

0 голосов
/ 14 апреля 2020

Вы должны использовать явные join s:

INSERT INTO [Workfiles].[dbo].[PickupAudit]
([HHBranch],[HHOrder],[HHCustomer],[HHShipTo],[EquipID],[EQStatus],[PickupNo],[StatusDate])    
    SELECT RH.kbranch, RH.kordnum, RH.kcustnum, RH.custsnum, RD.kpart, EQ.eqpstatus, RH.[program], GETDATE()
    FROM TEST.dbo.renthead RH JOIN
         TEST.dbo.rentdetl RD
         ON RH.kbranch = RD.kbranch AND
            RH.kordnum = RD.kordnum AND 
            RH.program NOT LIKE 'OPSS%' JOIN
         TEST.dbo.equip EQ
         ON EQ.kequipnum = RD.kpart JOIN
         inserted i
         ON RD.kpart = i.kequipnum;

Для производительности вам нужны индексы для столбцов, используемых в JOIN s, в следующем порядке:

  • TEST.dbo.rentdetl(kpart, kbanch, kordnum)
  • TEST.dbo.equip(kequipnum)
  • TEST.dbo.renthead(kbranch, kbanch, program)
...