Langsames Delete

gruen

Neuer Benutzer
Beiträge
2
Hallo Forum!

Ich entwerfe gerade eine simple Datenbank um ein paar Inspektionsergebnisse zu speichern. Dafür nutze ich SQL Server 2014 Express auf einem Windows 7 PC. Damit die Datenbank nicht zu voll wird, möchte ich alte Daten in regelmäßigen Abständen löschen.

Momentan habe ich eine Tabelle 'Objects' mit ca. 175000 Einträgen und eine Tabelle 'Defects' mit ca. 350000 Einträgen. 'Objects' hat eine Spalte 'ObjectId' als Primärschlüssel und 'Defects' hat im Schnitt zwei Einträge pro 'ObjectId'. Ich lösche jeweils die ca. 50000 Einträge mit den kleinsten ObjectIds.

Das Löschen in 'Objects' dauert ca. 200 ms.
Das Löschen in 'Defects' dauert ca. 3000 ms.

Mit dem Management Studio erzeugte CREATE-Skripte sehen folgendermaßen aus:

[...]
CREATE TABLE [dbo].[Defects](
[ObjectId] [bigint] NOT NULL,
[DefectId] [int] NOT NULL
) ON [PRIMARY]
[...]
CREATE CLUSTERED INDEX [IX_Defects] ON [dbo].[Defects]
(
[ObjectId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
[...]
CREATE TABLE [dbo].[Objects](
[ObjectId] [bigint] NOT NULL,
[EjectDateTime] [datetime2](2) NOT NULL,
PRIMARY KEY CLUSTERED
(
[ObjectId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
[...]

Meine Löschanweisungen sind:

delete from Defects where objectid <= X und
delete from Objects where objectid <= X

Der gruppierte Index in 'Defects' scheint mir nicht zu helfen.
Kann mir jemand sagen, warum das Löschen in 'Defects' so langsam ist, bzw. wie ich es beschleunigen kann?
Vielen Dank schon mal!

- Michael
 
Werbung:
Mit Performance Problemen habe ich wenig Erfahrung aber:
a) Den Index kannst du einfach mal droppen und neu erstellen.
b) Führe deine Anweisung mal im Management Studio mit "tatsächlichem Ausführungsplan einschließen" aus. Das ist ein Schalter bzw. Strg + M vor dem ausführen.
 
Löschen ist oft eine vergleichsweise langsame Operation bei Datenbanken.

Es muss ja nicht nur der Datensatz selbst gelöscht werden, es wird ja auch geprüft ob abhängige Datensätze existieren, in Deinem Fall muss bei einem Löschen in den Defects geprüft werden ob dazu noch ein Object existiert.
 
es wird ja auch geprüft ob abhängige Datensätze existieren, in Deinem Fall muss bei einem Löschen in den Defects geprüft werden

Wollt ich auch schon sagen, aber ich sehe keine RI-Constraints. Entweder hat er die nur nicht gezeigt oder es gibt keine. In der andere Tabelle wird nach dem PK gelöscht, da könnte ein Index greifen. Allerdings wird ein recht großer Teil gelöscht. Man müßte den Plan betrachten.
 
Ich sehe das jetzt auch nicht als so kritisch an wenn wirklich nur der Delete-Vorgang so lange dauert und dieser nicht mehrmals täglich laufen muss. Aber der Ausführungsplan sollte Auskunft geben.
 
Wenn die 3 Sekunden wirklich tragisch sind, vllt. einfach einen non-clustered Index verwenden?
Da du eine "simple Datenbank" baust, wirst du sowieso keine Vorteile aus dem Clustered Index ziehen...
 
Werbung:
Hallo und danke für die hilfreichen Antworten.
Die Vorschläge habe ich alle ausprobiert und dabei habe ich auch wieder einiges über Datenbanken gelernt.
Im Endeffekt lag es an etwas, was mein Programm macht, was ich hier aber gar nicht erwähnt hatte. (Asche über mein Haupt)
Ich habe nach jedem Löschvorgang DBCC SHRINKDATABASE(0) ausgeführt, was dazu geführt haben muss, dass mindestens der nächste Löschvorgang deutlich langsamer wurde.
Auf dieses Schrumpfen der Datenbank sollte ich aber verzichten können.
Jetzt dauert das Löschen in 'Objects' nur noch 100 ms und in 'Defects' 200 ms.
Vielen Dank nochmal!
- Michael
 
Zurück
Oben