Testen der Leistung von Scalar vs Tabellenwertfunktionen in SQL Server

8

OK, also habe ich eine ganze Reihe von Artikeln gelesen, die darauf hindeuten, dass Tabellenwertfunktionen und Cross-Apply bessere Performance als ein Skalar-UDF bieten. Ich wollte meine Funktion auf beide Arten schreiben und dann testen, um zu sehen, welche besser ist - aber ich kann nicht herausfinden, was ich verwenden soll / suchen, um zu verstehen, welche die bessere Option ist.

Ich benutze SQL Server 2005. Ich habe versucht, den geschätzten Ausführungsplan auszuführen, den tatsächlichen Ausführungsplan und analysiere die Abfrage im Datenbank-Engine-Tuning-Advisor und ich weiß nicht, was es mir zu sagen versucht.

>

Mit showplan_all on / off sieht es so aus, als würde die tabellenbasierte Funktion mehr cpu 1.157e-06 vs. 8.3e-05 verwenden, aber die Tabellenfunktion hat einen Gesamtteilbaumkosten von 0.000830157 gegenüber 0.01983356.

Die Abfragekosten der Tabellenwertfunktion scheinen auch höhere Kosten zu haben als die Skalarwerte. Obwohl ich dachte, es sollte die bessere Option sein.

Obwohl ich selbst gerne beweisen möchte, welches die bessere Leistung bringt - ich bin mir nicht sicher, worauf ich in diesen Tools achten soll - also wären alle Vorschläge willkommen!

Ich muss einen akademischen Jahreswert (basierend auf einem Datumsbereich in der Datenbank) basierend auf einem Kalenderdatum erhalten, damit der Funktionsinhalt darunter liegt - also ob ich skalar oder tabellenbasiert bin. Dieses Jahr fließt in andere Anfragen ein.

%Vor%

Danke !!

    
Jen 15.12.2010, 06:35
quelle

1 Antwort

16

Sie sehen möglicherweise nicht die erwarteten Leistungssteigerungen, da Ihre Tabellenfunktion multifunktional und nicht inline ist. Multi-Funktions-TVFs müssen auf die gleiche Weise wie skalare UDFs ausgeführt werden - einmal pro Zeile -, also gibt es sehr wenig Gewinn.

Nach dem Beispiel in diesem Artikel von Itzik Ben-Gan (der den Vorteile von In-Line-TVFs), stellen Sie den folgenden Test:

Erstellen Sie eine Nummerntabelle mit 1 Million Zeilen:

%Vor%

Führen Sie eine Million Ausführungen Ihres TVF mit dem folgenden Code aus:

%Vor%

Auf meinem System zeigte dies eine durchschnittliche Laufzeit von 83 Sekunden für drei Ausführungen, wobei DBCC dropcleanbuffers zwischen jeder Ausführung ausgeführt wurde.

Wenn Sie einen ähnlichen Test für Ihre skalare Funktion durchführen, sollten Sie eine bessere Vorstellung von der vergleichenden Leistung haben.

Der Test hat auch gezeigt, dass es sich um einen Fehler in Ihrer Funktion handelt. Wenn das AcademicYear.StartDate auf "2010-09-01" gesetzt ist, ist das für eine Eingabe von "1900-01-01" zurückgegebene akademische Jahr 1789, wo es so aussieht, als wäre 1899 zu erwarten.

Um die beste Leistung zu erhalten, müssen Sie den TVF in In-Line konvertieren. Ich habe folgendes gefunden, was den Bug korrigiert:

%Vor%

Dies hatte eine durchschnittliche Zeit von 8,9 Sekunden über drei Läufe - fast zehnmal schneller.

Die andere Sache, die Sie beachten sollten, ist, dass der Leistungsvorteil durch die Verwendung von TVF vernachlässigbar ist, es sei denn, Sie wenden es auf mehrere Zeilen an, wie in diesem Test. Wenn Sie es nur für einen Wert verwenden, werden Sie nicht viel Nutzen sehen, es sei denn, Sie haben Tausende von Instanzen der Funktion parallel ausgeführt.

    
Ed Harper 15.12.2010, 12:13
quelle