Wenn man bei Datenbanken komplexere Verarbeitungen durchführen muss, kommt man meist um die Verwendung eines cursors nicht herum. Doch jeder, der schon mal einen cursor verwendet hat kennt bestimmt das Problem: Das Statement zum Sammeln der Daten ist geschrieben und funktioniert, die Ausführung dauert nur wenige Sekunden. Jetzt noch den cursor aufsetzen und den Durchlauf testen. Und merkwürdigerweise dauert dasselbe Statement mit einem Cursor wesentlich länger – der Faktor 100 ist hier keine Seltenheit.
declare @custid t_d_id declare @name varchar(255) declare @firstname varchar (255) declare c cursor for select cu.r_customerid, t_lastname, t_firstname from [sql-uptime-sht].uptimedata.dbo.customer cu open c fetch next from c into @custid, @name, @firstname while @@fetch_status = 0 begin print @custid fetch next from c into @custid, @name, @firstname end close c deallocate c
Langsame Verarbeitung des cursors
Das liegt daran, dass der Standardcursortyp ein dynamischer cursor ist. D.h. der SQL-Server prüft die Bedingungen bei jedem fetch-Aufruf und das zieht die Performance so deutlich nach unten.
Abhilfe kann hier ein static local cursor schaffen. Dabei kopiert der Server die Ergebnismenge in die tempdb und liefert die Ergebnisse aus dieser temporären Datenquelle – was wesentlich performanter ist. Im Vergleich sind zwischen der reinen Abfrage und dem Durchlauf mittels eines static local cursors kaum noch Unterschiede festzustellen.
declare @custid t_d_id declare @name varchar(255) declare @firstname varchar (255) declare c cursor static local for select cu.r_customerid, t_lastname, t_firstname from [sql-uptime-sht].uptimedata.dbo.customer cu open c fetch next from c into @custid, @name, @firstname while @@fetch_status = 0 begin print @custid fetch next from c into @custid, @name, @firstname end close c deallocate c
static local cursor als schneller Variante