Ve většině případů je nejlepší vyhnout se skalárně hodnotným funkcím, které odkazují na tabulky, protože (jak řekli jiní) jsou to v podstatě černé skříňky, které je třeba spustit jednou pro každý řádek a nelze je optimalizovat modulem plánu dotazů. Proto mají tendenci se škálovat lineárně, i když přidružené tabulky mají indexy.
Možná budete chtít zvážit použití funkce s hodnotou vložené tabulky, protože jsou vyhodnocovány inline s dotazem a lze je optimalizovat. Získáte požadované zapouzdření, ale výkon při vkládání výrazů přímo do příkazu select.
Jako vedlejší efekt toho, že jsou inline, nemohou obsahovat žádný procedurální kód (žádná deklarace @proměnná; set @proměnná =..; return). Mohou však vrátit několik řádků a sloupců.
Své funkce byste mohli přepsat nějak takto:
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
);
Syntaxe pro jejich použití je také trochu odlišná:
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)