Ich habe ein kleines Leistungsproblem mit einem meiner Datenbank-Trigger in meiner MS-SQL Server 2014-Datenbank.Leistungsprobleme mit UPDATE in AFTER UPDATE Auslöser
CREATE TRIGGER [dbo].[TRG_T_TPM_Vehicle_Update] ON [dbo].[T_TPM_Vehicle]
AFTER UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
UPDATE T_TPM_Vehicle SET LastUpdated = getdate()
WHERE Vehicle_Number IN (SELECT Vehicle_Number FROM inserted)
UPDATE T_TPM_Vehicle SET [DisturbedSince] = getdate()
WHERE Vehicle_Number IN (SELECT Vehicle_Number FROM inserted WHERE inserted.Emergency_Stop = 1)
AND Vehicle_Number IN (SELECT Vehicle_Number FROM deleted WHERE deleted.Emergency_Stop = 0)
INSERT INTO T_TPM_Vehicle_HistoricalData
([Vehicle_Ref]
,[Vehicle_Number]
,[Vehicle_Type]
,[Pos_X]
,[Pos_Y]
,[Alpha]
,[LastAutoPos_X]
,[LastAutoPos_Y]
,[LastAutoAlpha]
,[Automatic]
,[Manual]
,[Blocked]
,[Loaded]
,[Stoped]
,[Emergency_Stop]
,[User_Required]
,[BatteryAlmostEmpty]
,[BatteryEmpty]
,[BatteryLevel]
,[ChargingRelaisEnable]
,[NavOK]
,[PowerOn]
,[Available]
,[OperatingMinutes]
,[UpdateOperatingMinutes]
,[DataChangedByVIS]
,[Blockingsreleased]
,[Cancelled]
,[ProductID]
,[HUIdent1]
,[HUIdent2]
,[HUType]
,[DisturbedSince])
SELECT inserted.[Vehicle_Ref]
,inserted.[Vehicle_Number]
,inserted.[Vehicle_Type]
,inserted.[Pos_X]
,inserted.[Pos_Y]
,inserted.[Alpha]
,inserted.[LastAutoPos_X]
,inserted.[LastAutoPos_Y]
,inserted.[LastAutoAlpha]
,inserted.[Automatic]
,inserted.[Manual]
,inserted.[Blocked]
,inserted.[Loaded]
,inserted.[Stoped]
,inserted.[Emergency_Stop]
,inserted.[User_Required]
,inserted.[BatteryAlmostEmpty]
,inserted.[BatteryEmpty]
,inserted.[BatteryLevel]
,inserted.[ChargingRelaisEnable]
,inserted.[NavOK]
,inserted.[PowerOn]
,inserted.[Available]
,inserted.[OperatingMinutes]
,inserted.[UpdateOperatingMinutes]
,inserted.[DataChangedByVIS]
,inserted.[Blockingsreleased]
,inserted.[Cancelled]
,inserted.[ProductID]
,inserted.[HUIdent1]
,inserted.[HUIdent2]
,inserted.[HUType]
,inserted.[DisturbedSince]
FROM inserted
END
Was im Grunde tut es ist es die Lastupdated Spalte für alle Zeilen in eingefügt setzt und die DisturbedSince Spalte für eine Teilmenge der eingefügten Zeilen.
Schließlich werden die eingefügten Zeilen in eine Protokolltabelle kopiert. (Jede Änderung einer Zeile muss für zwei Tage gespeichert werden). Ältere Daten werden durch einen Wartungsauftrag gelöscht.
Da wir bis zu ~ 300 Zeilen pro Sekunde aktualisiert haben (Updates für Zeilen können zusammengelegt werden) Wir erstellen eine große Menge an Daten und rekursiven Updates.
Ich habe jetzt die INSTEAD OF UPDATE-Trigger gefunden, die das von meinem Trigger verursachte rekursive UPDATE-Problem zu lösen scheinen, aber ich müsste jede Zeile der eingefügten Tabelle nacheinander mit einer Update-Anweisung im Trigger verarbeiten.
Ich bin mir nicht sicher, ob das wirklich schneller ist. Hat jemand von euch eine Empfehlung?
Was ich wirklich brauche ist, die Datenzeilen zu optimieren/zu erweitern, bevor sie an die Tabelle gesendet werden. Gibt es einen Ansatz dafür?
z.B .: Etwas wie:
CREATE TRIGGER ... INSTEAD OF UPDATE
AS
BEGIN
UPDATE inserted SET LastUpdated = getdate()
UPDATE inserted SET DisturbedSince
WHERE Vehicle_Number IN (SELECT Vehicle_Number FROM inserted WHERE inserted.Emergency_Stop = 1)
AND Vehicle_Number IN (SELECT Vehicle_Number FROM deleted WHERE deleted.Emergency_Stop = 0)
"SAVE INSERTED"
END
und ein AFTER UPDATE TRIGGER mit der Speicherung der geänderten Daten in der History-Tabelle.
Vielen Dank für Anregungen.
Thomas
Für welches RDBMS ist das? Trigger sind ** sehr ** anbieterspezifisch - bitte fügen Sie ein Tag hinzu, um anzugeben, ob Sie 'mysql',' postgresql', 'sql-server',' oracle' oder 'db2' verwenden - oder etwas ganz anderes. –
"Ich müsste jede Zeile der eingefügten Tabelle nacheinander mit einer Update-Anweisung im Trigger verarbeiten." - Ähm, warum glaubst du das? –
@Marc: Es ist eine MS-SQL Server 2014-Datenbank. Ich habe das zu meiner Frage hinzugefügt. –