2013-05-08 2 views
13

Ich habe eine Datenbanktabelle (auf SQL Server 2012 Express ausgeführt), die ~ 60.000 Zeilen enthält.Löschen einer großen Anzahl von Datensätzen dauert sehr lange

ich den folgenden Code verwende alte Zeilen zu löschen:

//Deleting CPU measurements older than (oldestAllowedTime) 
var allCpuMeasurementsQuery = from curr in msdc.CpuMeasurements where 
    curr.Timestamp < oldestAllowedTime select curr; 
foreach (var cpuMeasurement in allCpuMeasurementsQuery) 
{ 
    msdc.CpuMeasurements.Remove(cpuMeasurement); 
} 

Wenn die Anzahl der gelöschten Zeilen groß ist (~ 90% oder mehr der Datensätze in den Tabellen gelöscht werden) nimmt den Betrieb außergewöhnlich lange. Es dauert ungefähr 30 Minuten, um diesen Vorgang auf einer relativ starken Maschine (Intel I5 Desktop) zu beenden.

  1. scheint dies ein normales Verhalten?

  2. irgendwelche Ideen darüber, was ich tun kann, um die Betriebszeit zu reduzieren?

Danke,

+3

Schauen Sie DeleteAllOnSubmit, es kann helfen. – DavidB

+2

AFAIK Was Sie tun, ist 60.000+ Befehle zum Löschen der Datenbank. Wenn Sie stattdessen nur einen Befehl oder mehrere hundert Befehle oder weniger ausführen könnten, hätten Sie dieses Leistungsproblem nicht. – Renan

+4

Entity Framework ist nicht gut in dieser Art von Sache. Es könnte am besten sein, eine gespeicherte Prozedur zu erstellen, die Sie im Zeitstempel übergeben, und löscht alle Datensätze auf diese Weise. – Belogix

Antwort

17

Entity Framework ist nicht sehr gut im Umgang mit Bulk-Operationen wie folgt. Sie sollten ExecuteStoreCommand verwenden, um SQL in solchen Situationen direkt gegen die Datenquelle auszuführen.

var deleteOld = "DELETE FROM CpuMeasurements WHERE curr.Timestamp < {0}"; 
msdc.ExecuteStoreCommand(deleteOld, oldestAllowedTime); 

Dadurch brauchen Sie nicht die Objekte in den Speicher zu laden (nur um sie zu löschen) und in die Datenbank Tausende von Löschbefehle zu erteilen.

+0

+1, So habe ich es auch gelöst –

+2

Ich schätze alle Vorschläge hier. Ich wähle diese Lösung für jetzt, da es am einfachsten scheint (zumindest für mich). Ich denke, dass die anderen hier erwähnten Lösungen vielversprechend erscheinen (EntityFramework.Extended), und ich werde sie überprüfen, wenn sich die Dinge beruhigen. – OSH

13

Sie bei EntityFramework.Extended aussehen sollte es erstellt wurde sowohl mit Massenlöschungen und Updates zu helfen.

es verwenden, können Sie einfach tun:

msdc.CpuMeasurements.Delete(curr => curr.Timestamp < oldestAllowedTime); 
-1

große Mengen an Daten löschen kann eine lange Zeit in Anspruch nehmen.

Sie müssen möglicherweise die SQL aus Ihrer Anwendung verschieben und es als einzelnes SQL-Skript über SQL Server Agent ausführen. Es könnte zum Beispiel einmal pro Tag während der ruhigsten Zeit ausgeführt werden.

5

Der Grund dafür ist, dass Sie eine DB-Aktualisierung für jeden einzelnen Datensatz ausführen. Sie müssen ein Massenupdate durchführen.

EntityFramework.extended kann mit diesem Szenario umgehen.