In den meisten Fällen ist es am besten, Skalarwertfunktionen zu vermeiden, die auf Tabellen verweisen, da es sich (wie andere bereits sagten) im Grunde genommen um Black Boxes handelt, die einmal für jede Zeile ausgeführt werden müssen und nicht von der Abfrageplan-Engine optimiert werden können. Daher neigen sie dazu, linear zu skalieren, selbst wenn die zugehörigen Tabellen Indizes haben.
Möglicherweise möchten Sie die Verwendung einer Inline-Tabellenwertfunktion in Betracht ziehen, da sie inline mit der Abfrage ausgewertet werden und optimiert werden können. Sie erhalten die gewünschte Kapselung, aber die Leistung beim Einfügen der Ausdrücke direkt in die Select-Anweisung.
Als Nebeneffekt der Einbettung können sie keinen prozeduralen Code enthalten (kein @variable deklarieren; @variable =.. setzen; return). Sie können jedoch mehrere Zeilen und Spalten zurückgeben.
Sie könnten Ihre Funktionen etwa so umschreiben:
create function usf_GIS_GET_LAT(
@City varchar (30),
@State char (2)
)
returns table
as return (
select top 1 lat
from GIS_Location with (nolock)
where [State] = @State
and [City] = @City
);
GO
create function usf_GIS_GET_LON (
@City varchar (30),
@State char (2)
)
returns table
as return (
select top 1 LON
from GIS_Location with (nolock)
where [State] = @State
and [City] = @City
);
Die Syntax, um sie zu verwenden, ist ebenfalls etwas anders:
select
Lat.Lat,
Lon.Lon
from
Address_Location with (nolock)
cross apply dbo.usf_GIS_GET_LAT(City,[State]) AS Lat
cross apply dbo.usf_GIS_GET_LON(City,[State]) AS Lon
WHERE
ID IN (SELECT TOP 100 ID FROM Address_Location WITH(NOLOCK) ORDER BY ID DESC)