Hallo,
Ich habe folgendes problem mit der Performance bei einer DELETE operation:
Die Operation löscht ca. ein Dutzend Datensätze in der Tabelle "VERSIONS". Diese hat den Primärschlüssel "VersionID". Dann gibt es noch die Tabelle "DEPENDENCIES" in der Abhängigkeiten zwischen den Versionen gespeichert werden und zwar über Fremdschlüsselverweise auf "VERSIONS.VersionID". Hierfür gibt es die Spalten "ParentID" und "ChildID".
Wenn ein Datensatz aus der Tabelle "VERSIONS" gelöscht wird, sollen logischerweise auch alle Datensätze der Tabelle "DEPENDENCIES" gelöscht werden, die sich auf diese Version beziehen, d.h. bei denen die Version in der Spalte "ParentID" oder "ChildID" eingetragen ist.
Bei der Fremschlüsseldefinition der Spalte "ParentID" habe ich hierfür die Löschregel "Cascade" angegeben. Leider kann ich nicht dasselbe für die Spalte "ChildID" machen. Dann gibt es immer den Fehler "Multiple Delete Paths", obwohl die beiden IDs nie gleich sein dürfen.
Deshalb habe ich diese Löschregel über den folgenden Trigger implementiert.
[highlight=sql]
USE [Performance\P3]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[T_VERSIONS_DTrig] ON [dbo].[VERSIONS] FOR DELETE AS
SET NOCOUNT ON
DELETE DEPENDENCIES FROM deleted, DEPENDENCIES WHERE deleted.VersionID = DEPENDENCIES.ChildID
[/highlight]
Das Problem ist nun, dass die Ausführung des Triggers sehr langsam ist. Auf meinem lokalen Rechner werden 5 Sekunden benötigt, auf einem anderen Server im WAN sogar 22 Sekunden, obwohl nur 41 Datensätze betroffen sind.
Der Server Profiler meldet 7791 Reads und 1800 Writes für die Operation.
Das seltsame ist: Wenn ich den Befehl "DELETE DEPENDENCIES FROM deleted ...." weglasse, ändert sich daran praktisch nichts. Erst, wenn ich den Trigger ganz lösche, braucht die Operation fast keine Zeit mehr.
Ich vermute, dass die Zeit damit verplempert wird, die temporäre Tabelle "deleted" anzulegen. In der der Tabelle "VERSIONS" gibt es nämlich eine Spalte mit BLOBs, die auch mal mehrere MB groß sein können.
Hat jemand eine Idee, ob das der Grund sein kann, oder wie man das ganze schneller kriegt? Gibt es vielleicht eine Möglichkeit das BLOB bei der Operation auszunehmen?
Was mir auch schleierhaft ist: Warum braucht die Ausführung auf dem anderen Server im WAN so viel länger?
Ich habe folgendes problem mit der Performance bei einer DELETE operation:
Die Operation löscht ca. ein Dutzend Datensätze in der Tabelle "VERSIONS". Diese hat den Primärschlüssel "VersionID". Dann gibt es noch die Tabelle "DEPENDENCIES" in der Abhängigkeiten zwischen den Versionen gespeichert werden und zwar über Fremdschlüsselverweise auf "VERSIONS.VersionID". Hierfür gibt es die Spalten "ParentID" und "ChildID".
Wenn ein Datensatz aus der Tabelle "VERSIONS" gelöscht wird, sollen logischerweise auch alle Datensätze der Tabelle "DEPENDENCIES" gelöscht werden, die sich auf diese Version beziehen, d.h. bei denen die Version in der Spalte "ParentID" oder "ChildID" eingetragen ist.
Bei der Fremschlüsseldefinition der Spalte "ParentID" habe ich hierfür die Löschregel "Cascade" angegeben. Leider kann ich nicht dasselbe für die Spalte "ChildID" machen. Dann gibt es immer den Fehler "Multiple Delete Paths", obwohl die beiden IDs nie gleich sein dürfen.
Deshalb habe ich diese Löschregel über den folgenden Trigger implementiert.
[highlight=sql]
USE [Performance\P3]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[T_VERSIONS_DTrig] ON [dbo].[VERSIONS] FOR DELETE AS
SET NOCOUNT ON
DELETE DEPENDENCIES FROM deleted, DEPENDENCIES WHERE deleted.VersionID = DEPENDENCIES.ChildID
[/highlight]
Das Problem ist nun, dass die Ausführung des Triggers sehr langsam ist. Auf meinem lokalen Rechner werden 5 Sekunden benötigt, auf einem anderen Server im WAN sogar 22 Sekunden, obwohl nur 41 Datensätze betroffen sind.
Der Server Profiler meldet 7791 Reads und 1800 Writes für die Operation.
Das seltsame ist: Wenn ich den Befehl "DELETE DEPENDENCIES FROM deleted ...." weglasse, ändert sich daran praktisch nichts. Erst, wenn ich den Trigger ganz lösche, braucht die Operation fast keine Zeit mehr.
Ich vermute, dass die Zeit damit verplempert wird, die temporäre Tabelle "deleted" anzulegen. In der der Tabelle "VERSIONS" gibt es nämlich eine Spalte mit BLOBs, die auch mal mehrere MB groß sein können.
Hat jemand eine Idee, ob das der Grund sein kann, oder wie man das ganze schneller kriegt? Gibt es vielleicht eine Möglichkeit das BLOB bei der Operation auszunehmen?
Was mir auch schleierhaft ist: Warum braucht die Ausführung auf dem anderen Server im WAN so viel länger?
Comment