Laden...

Performance: Skalarfunktion als Parameter einer Tabellenwertfunktion

Letzter Beitrag vor 14 Jahren 3 Posts 844 Views
Performance: Skalarfunktion als Parameter einer Tabellenwertfunktion

verwendetes Datenbanksystem: SQL Server 2005/2008

Hallo.

Ich habe zur Zeit ein mächtiges Performance-Problem:

Wir haben eine Tabellenwertfunktion, welche mehrere Tausend Zeilen Daten ausspuckt. Als Parameter kann ein Zahlenwert übergeben werden. Dieser Wert wird meist durch eine Skalarfunktion berechnet. Also vereinfacht:

SELECT * FROM dbo.TABELLENFUNKTION(dbo.SKALARFUNKTION())

Diese Abfrage braucht eeeeewig! Wenn ich jetzt aber direkt einen Zahlenwert übergebe, ist der Server in einem Bruchteil der Zeit fertig. Jetzt meine Vermutung: Der Parser wertet nicht die Skalarfunktion aus und übergibt das Ergebnis an die Tabellenwertfunktion, sondern pro Zeile in der Tabelle wird die Skalarfunktion neu berechnet!

Ist das normal? Kann man das Verhalten ändern?

Bevor Fragen kommen: An der Struktur kann ich leider nicht viel ändern, das passt schon so im Kontext. Eine Alternative wäre eine 2. Tabellenfunktion, die den Skalarwert auf eine Variable setzt und die 1. Funktion aufruft, das geht genauso fix. Allerdings muss man dann die Tabellenspalten in der 2. Funktion einpflegen. Wir haben mehrere solche Konstellationen -> Wartungsaufwand!

Vielleicht hat ja einer ne Idee.

Lars

Edit: Performancemessung: mit Wert statt Skalarfunktion im Parameter ist der Aufruf ganze 25 Mal schneller!!

probiere mit:

declare @temp int /* oder entsprechender Typ */
set @temp = dbo.SKALARFUNKTION()

SELECT * FROM dbo.TABELLENFUNKTION(@temp)

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

Das wäre die logischste Idee, ja, leider nicht machbar:

Der Aufruf der Codezeile erfolgt aus einem View heraus, dort können keine Variablen deklariert werden. Die Tab-Funktion soll kein DB-User direkt aufrufen können. Auch eine normale Tabellenwertfunktion kann keine Variablen nutzen. Nur wenn man eine mit Zwischentabelle deklariert ist dies möglich. Dort allerdings hast du halt den Pflegeaufwand, jede Änderung der Spalten der Tabellenwertfunktion muss auch auch in der jeweiligen 2. Tabellenwertfunktion vorgenommen werden -> viel Wartungsaufwand, genau das möchte ich ja umgehen.
Die Funktion mit Parameter wird intern benötigt, die ohne extern. Der View generiert ja seine Spalten von der zu Grunde liegenden Abfrage selbst, von daher war die die beste Lösung bisher.