Hallo Community,
ich habe da eine Funktion und einen Cursor, und beide läuft richtig lahm, dabei habe ich schon alles unternommen, um das ganze zu beschleunigen.
Zuerst die Problemstellung:
Es geht darum, herauszufinden ob eine Rechnung ins Jahr 2005 oder 2006 gehört. Dies mache ich Anhand von Belegen fest. Jeder Beleg hat ein eigenes Datum, und nun soll er pro Rechnung schauen, wieviele Beleg in 2005, bzw. wieviele in 2006 gehören. Je nachdem, wo der überwiegende Teil ist, dort in das Jahr soll diese Rechnung.
Nun habe ich die Funktion gestartet gehabt. Es betrifft 423.000 Rechnungen, also eine ganze Menge. Wie zu erwarten, ist mir mein Rechner abgeschmiert, nach 24 Tagen Laufzeit des Scripts, und es hat nichts gebracht, da ich keinen Cursor genutzt hatte (hatte gehofft, dann geht es schneller).
Nun habe ich folgende Dinge unternommen:
- alle relevanten Daten in eine neue Tabelle gesammelt, mit PK und Index
- alle entsprechenden Rechnungsnummern nochmals in eine weitere Tabelle, mit einem Feld "ZRA" (zeitliche Rechnungsabgrenzung), das mit 2005 oder 2006 gefüllt werden soll
- Cursor für die einzelnen Updatevorgänge gemacht
Naja, wie dem auch sei, es klappt zwar, aber sehr sehr schleppend. Und ich kann mir einfach nicht mehr vorstellen, woran das noch liegen kann.
1. Versuch auf unserem SQL2000 Cluster ... sehr langsam das ganze, und hat den Cluster unheimlich verlangsamt, so dass das Arbeiten auf den Datenbanken quasi unmöglich wurde
2. Versuch auf unserer kleinen Testumgebnung auf einerSQL2005´er Workstation, auf der nichts anderes läuft.
Insgesammt braucht er zurzeit auf der Testumgebung über zwei Tage für 2000 Rechnungen. Das ist quasi unakzeptabel. Vielleicht könnt Ihr Euch sowohl den Cursor als auch die Funktion mal anschauen. Findet Ihr das etwas, wodurch ich das ganze evtl. beschleunigen könnte?
Funktion:
declare @t table (PRecNr decimal(10), PicNr decimal(18), LDatum datetime) declare @zdatum datetime
insert into @t
select precnr, picnr, adatum
from temp_sozis where precnr = @precnr
set @zdatum = ( select min(zeitstempel) from temp_sozis
where precnr = @precnr and vorgangsart = 'Z'
)
update t
set ldatum = ( select max(von) from temp_sozis where picnr = t.picnr)
from @t t
where ldatum < ( select max(von) from temp_sozis where picnr = t.picnr)
update t
set ldatum = ( select max(bis) from temp_sozis where picnr = t.picnr)
from @t t
where ldatum < ( select max(bis) from temp_sozis where picnr = t.picnr)
if (select count(*) from @t where year(ldatum) >= @jahr) -- angebenes Jahr und später
<= (select count(*) from @t where year(ldatum) < @jahr) -- Vorjahre
and @zdatum <= @zradatum
set @jahr = @jahr - 1
return @jahr
end
Und noch der Cursor:
USE Testumgebung
GO
DECLARE sascha CURSOR FOR
SELECT *
FROM temp_sozis_precnr
WHERE zra not in (2005,2006)
OPEN sascha
GO
FETCH NEXT FROM sascha
GO
while( @@fetch_status = 0 )
begin
UPDATE temp_sozis_precnr SET zra = dbo.ZRA_sozis(precnr, 2006, '31.3.2006')
WHERE CURRENT OF sascha
fetch next from sascha
end
CLOSE sascha
DEALLOCATE sascha
GO
Für Hinweise bin ich super dankbar.
Lieben Gruß
Saschbert
ich habe da eine Funktion und einen Cursor, und beide läuft richtig lahm, dabei habe ich schon alles unternommen, um das ganze zu beschleunigen.
Zuerst die Problemstellung:
Es geht darum, herauszufinden ob eine Rechnung ins Jahr 2005 oder 2006 gehört. Dies mache ich Anhand von Belegen fest. Jeder Beleg hat ein eigenes Datum, und nun soll er pro Rechnung schauen, wieviele Beleg in 2005, bzw. wieviele in 2006 gehören. Je nachdem, wo der überwiegende Teil ist, dort in das Jahr soll diese Rechnung.
Nun habe ich die Funktion gestartet gehabt. Es betrifft 423.000 Rechnungen, also eine ganze Menge. Wie zu erwarten, ist mir mein Rechner abgeschmiert, nach 24 Tagen Laufzeit des Scripts, und es hat nichts gebracht, da ich keinen Cursor genutzt hatte (hatte gehofft, dann geht es schneller).
Nun habe ich folgende Dinge unternommen:
- alle relevanten Daten in eine neue Tabelle gesammelt, mit PK und Index
- alle entsprechenden Rechnungsnummern nochmals in eine weitere Tabelle, mit einem Feld "ZRA" (zeitliche Rechnungsabgrenzung), das mit 2005 oder 2006 gefüllt werden soll
- Cursor für die einzelnen Updatevorgänge gemacht
Naja, wie dem auch sei, es klappt zwar, aber sehr sehr schleppend. Und ich kann mir einfach nicht mehr vorstellen, woran das noch liegen kann.
1. Versuch auf unserem SQL2000 Cluster ... sehr langsam das ganze, und hat den Cluster unheimlich verlangsamt, so dass das Arbeiten auf den Datenbanken quasi unmöglich wurde
2. Versuch auf unserer kleinen Testumgebnung auf einerSQL2005´er Workstation, auf der nichts anderes läuft.
Insgesammt braucht er zurzeit auf der Testumgebung über zwei Tage für 2000 Rechnungen. Das ist quasi unakzeptabel. Vielleicht könnt Ihr Euch sowohl den Cursor als auch die Funktion mal anschauen. Findet Ihr das etwas, wodurch ich das ganze evtl. beschleunigen könnte?
Funktion:
declare @t table (PRecNr decimal(10), PicNr decimal(18), LDatum datetime) declare @zdatum datetime
insert into @t
select precnr, picnr, adatum
from temp_sozis where precnr = @precnr
set @zdatum = ( select min(zeitstempel) from temp_sozis
where precnr = @precnr and vorgangsart = 'Z'
)
update t
set ldatum = ( select max(von) from temp_sozis where picnr = t.picnr)
from @t t
where ldatum < ( select max(von) from temp_sozis where picnr = t.picnr)
update t
set ldatum = ( select max(bis) from temp_sozis where picnr = t.picnr)
from @t t
where ldatum < ( select max(bis) from temp_sozis where picnr = t.picnr)
if (select count(*) from @t where year(ldatum) >= @jahr) -- angebenes Jahr und später
<= (select count(*) from @t where year(ldatum) < @jahr) -- Vorjahre
and @zdatum <= @zradatum
set @jahr = @jahr - 1
return @jahr
end
Und noch der Cursor:
USE Testumgebung
GO
DECLARE sascha CURSOR FOR
SELECT *
FROM temp_sozis_precnr
WHERE zra not in (2005,2006)
OPEN sascha
GO
FETCH NEXT FROM sascha
GO
while( @@fetch_status = 0 )
begin
UPDATE temp_sozis_precnr SET zra = dbo.ZRA_sozis(precnr, 2006, '31.3.2006')
WHERE CURRENT OF sascha
fetch next from sascha
end
CLOSE sascha
DEALLOCATE sascha
GO
Für Hinweise bin ich super dankbar.
Lieben Gruß
Saschbert
Comment