Laden...

Datensätze in Chunks löschen: Gibt es eine einfachere Lösung?

Erstellt von ErfinderDesRades vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.226 Views
ErfinderDesRades Themenstarter:in
5.299 Beiträge seit 2008
vor 5 Jahren
Datensätze in Chunks löschen: Gibt es eine einfachere Lösung?

verwendetes Datenbanksystem: SqlServer

Ich hab eine komplizierte Abfrage, die läuft recht lange und löscht recht viel.
Der Db-Admin wünscht, dass die Löscherei in Chunks von 500 Datensätzen erfolgt.
Da habich eine komplizierte Lösung, wo ich erst nachzähle, wieviele denn gelöscht werden, dann die Anzahl der dafür benötigten Chunks, und dann in einer While-Schleife abfahren.

Etwas einfacher, aber iwie auch skurril ist eine Lösung, wo ich das Output-Feature dazu nutze, herauszubekommen, wieviele Datensätze gelöscht wurden, und wenn weniger als ChunkSize, die Schleife verlassen - beispielCode (b.Bed auskopieren + testen):


--Chunken mit dem Output-Feature
create table #todelete(numb int )
create table #todelete2(numb int )
declare @count int=0
while @count<100
	Begin
		insert into #todelete values(@count)
		insert into #todelete2 values(@count*2)
		select @count=@count+1
	end

declare @ChunkSize1 int = 15
create table #deleteds(numb int )
declare  @delCount int = @ChunkSize1
while @delCount = @ChunkSize1
	Begin
		Begin TRANSACTION;
			Delete Top (@ChunkSize1) td
			output 1 as numb into #deleteds
			FROM #todelete td
			join #todelete2 td2 on td.numb=td2.numb
		COMMIT TRANSACTION;
		select  @delCount= count(*) from #deleteds;
		select  @delCount
		truncate table #deleteds;
	End

select   count(*) Rest from #todelete;
drop table #deleteds
drop table #todelete
drop table #todelete2

(das mit toDelete, toDelete2 soll andeuten, dass die Abfrage komplex ist)
Meine Frage: Gibts da nicht was einfacheres?

Der frühe Apfel fängt den Wurm.

C
2.121 Beiträge seit 2010
vor 5 Jahren

Sieht schon etwas kompliziert aus. Eine leere Zuweisung an select @delCount ?

Sieh dir mal @@ROWCOUNT an. Das sollte auf die Anzahl der Zeilen gesetzt werden die soeben gelöscht wurden.

Wie viele Datensätze sind es denn im Normalfall? Ich würde mit dem Admin klären warum es nur 500 pro Vorgang sein sollen. Mit dem ganzen Overhead und ständigem neu joinen von Datensätzen machst du eventuell mehr Performance kaputt als wenn du einfach am Stück ein paar tausend Datensätze auf einmal löschst.

T
433 Beiträge seit 2006
vor 5 Jahren

Ich nutze für 'Chunk' Operation immer dieses Skript:


WHILE ( 1 = 1 )
    BEGIN
        BEGIN TRANSACTION;
    
        DELETE TOP ( 500 )
        FROM    dbo.table1
        WHERE   condition IS NULL;
    
        IF @@ROWCOUNT = 0 -- terminating condition;
            BEGIN
                COMMIT TRANSACTION;
                BREAK;
            END;
    
        COMMIT TRANSACTION;
    END;

Die Anzahl der Rows ist natürlich immer situationsabhängig.
Musst du Millionen von Datensätzen löschen, würde es mit 500 länger dauern, als wenn du z.B. 10000 auf einmal löscht.
Generell solltest aber das machen was dein DBA dir vorgibt. Vorausgesetzt er kennt sich aus 😉

C
2.121 Beiträge seit 2010
vor 5 Jahren

Vorausgesetzt er kennt sich aus

Exakt das wollte ich mit meinem Tip sicherstellen 😉
Der Gedanke "oh das dauert sicher lange, mach lieber mal in kleinen Schritten" kommt auch EDV-nahen Personen, die unter anderem einen Datenbankserver mit verwalten (müssen) und sich aber nicht so richtig auskennen. Daher lieber doch mal nachfragen.
Wichtig ist auch Performancetests zu machen. Am besten immer wieder loggen wie lange etwas dauert und bei Bedarf eingreifen.
Und immer dran denken: wenn die DB lahm ist kriegt der es ab der sie programmiert hat, nicht der von dem Tips kamen.

Übrigens kann man natürlich nicht nur zu kleine Schritte machen sondern auch zu große. Immer alles auf einmal tun wollen kann dazu führen dass ein Logfile überläuft. Je nach DB und Einstellungen. Es kommt immer drauf an...