I de fleste tilfælde er det bedst at undgå skalarvurderede funktioner, der refererer til tabeller, fordi de (som andre sagde) dybest set er sorte bokse, der skal køres én gang for hver række og ikke kan optimeres af forespørgselsplanmotoren. Derfor har de en tendens til at skalere lineært, selvom de tilknyttede tabeller har indekser.
Du vil måske overveje at bruge en inline-tabel-vurderet funktion, da de evalueres inline med forespørgslen og kan optimeres. Du får den indkapsling, du ønsker, men ydelsen ved at indsætte udtrykkene lige i select-sætningen.
Som en bivirkning af at være inlinet kan de ikke indeholde nogen procedurekode (ingen erklære @variabel; sæt @variabel =..; return). De kan dog returnere flere rækker og kolonner.
Du kan omskrive dine funktioner noget som dette:
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
);
Syntaksen for at bruge dem er også lidt anderledes:
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)