Summenwert einer Reihe

Dies ist ein beliebtes Beispiel für Informatikstudenten im Anfangsstadium, um die Auswirkungen effizienter Algorithmen zu demonstrieren. Also auch hier nicht unbedingt etwas, was man zwingend in einer Datenbank machen müßte, das sich aber durchaus mengenbasiert lösen läßt. Zu diesem Algorithmus gibt es eine kleinen Anekdote:

Dem "Entdecker" Carl-Friedrich Gauß wurde in der Schule die Aufgabe gestellt, die Summe aller Zahlen von 1 bis 100 zu berechnen. Alle Kinder rechneten los, Gauß schrieb kurz etwas auf seine Tafel und riss nach kurzer Zeit seinen Lehrer aus dessen Ruhepause. Die Formel stimmte natürlich! Wer es genauer nachlesen möchte, kann sich mal hier umschauen.

DECLARE @n BIGINT
SET @n = 100
SELECT (@n+@n*@n)/2
                     
-------------------- 
5050

(1 row(s) affected)

oder als UDF

CREATE FUNCTION dbo.achtsieben(@n BIGINT) 
RETURNS BIGINT
	AS
		BEGIN
    	RETURN (@n+@n*@n)/2
		END
GO
SELECT dbo.achtsieben(100)
DROP FUNCTION dbo.achtsieben
                     
-------------------- 
5050

(1 row(s) affected)

Zu dem Namen, den ich der Funktion gegeben habe, gibt es auch eine Anekdote:

Als ich unsere Mathematiker nach der "richtigen" Bezeichnung für diese Formel gefragt habe, kam als Antwort:

"Wir nennen das die 78-er Regel, da die Summe der Monate eines Jahres 78 ist."

Ein kurzer Test ergibt:

DECLARE @n BIGINT
SET @n = 12
SELECT (@n+@n*@n)/2
                     
-------------------- 
78

(1 row(s) affected)

Stimmt!

Nachtrag 27.08.2004: Auch im SQL Server kann man damit die Notwendigkeit zum Einsatz von effizienten Algorithmen demonstrieren. Dazu bauen wir uns mal folgendes Testskript zusammen:

DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
GO
DECLARE @start DATETIME
SET @start = GETDATE()
DECLARE @n BIGINT 
SET @n = 200000 
SELECT (@n+@n*@n)/2
SELECT GETDATE()-@start AS Zeit
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
GO
DECLARE @start DATETIME
DECLARE @n BIGINT 
DECLARE @result BIGINT 
SET @start = GETDATE()
SET @n = 1
SET @result = 0
WHILE @n <= 200000
	BEGIN
		SET @result = @result + @n
		SET @n = @n + 1
	END
SELECT @result
SELECT GETDATE()-@start AS Zeit

Nach Ausführung erhält man folgendes Ergebnis:

...
                     
-------------------- 
20000100000

(1 row(s) affected)

Zeit                                                   
------------------------------------------------------ 
1900-01-01 00:00:00.010

(1 row(s) affected)

...
                     
-------------------- 
20000100000

(1 row(s) affected)

Zeit                                                   
------------------------------------------------------ 
1900-01-01 00:00:01.513

(1 row(s) affected)

Während der Gauß Algorithmus fast augenblicklich das Ergebnis zurückliefern, braucht die iterative Methode deutlich länger!

Vielleicht mag das nicht viel erscheinen, aber jetzt stelle ich mir die Auswirkungen auf ein System vor, in dem ein solcher algorithmus in einer stark frequentierten Prozedur implementiert wurde, die mehrere Tausend Male pro Stunde aufgerufen wird. Nun sieht die Sache schon etwas anders aus. Jetzt mag man natürlich mit Caching argumentieren, aber in diesem Fall wird die Ausführung ohne

DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
GO

zwischen zwei Läufen der iterativen Methode auch nicht wirklich schneller

Zeit                                                   
------------------------------------------------------ 
1900-01-01 00:00:01.403

(1 row(s) affected)

Dies ist natürlich kein repräsentativer Test unter sterilen Testbedingungen, aber verdeutlicht doch die Notwendigkeit effizienter Algorithmen, auch, und vielleicht gerade, in T-SQL. 

Noch kein Feedback
Einen Kommentar hinterlassen

Ihre E-Mail-Adresse wird nicht auf dieser Seite angezeigt.
SchlechtExzellent
(Zeilenumbrüche werden zu <br />)
(For my next comment on this site)
(Allow users to contact me through a message form -- Your email will not be revealed!)
Dies ist ein Captcha Bild. Es wird benutzt, um Massenzugriffe von Robotern zu verhindern.
Bitte gib die Zeichen des obigen Bildes ein. (Groß/Kleinschreibung ist wichtig)
Trackback-Adresse für diesen Eintrag
Dies ist ein Captcha Bild. Es wird benutzt, um Massenzugriffe von Robotern zu verhindern.
Bitte gib die Zeichen des obigen Bildes ein. (Groß/Kleinschreibung ist wichtig)