Nella maggior parte dei casi, è meglio evitare funzioni con valori scalari che fanno riferimento a tabelle perché (come altri hanno affermato) sono fondamentalmente scatole nere che devono essere eseguite una volta per ogni riga e non possono essere ottimizzate dal motore del piano di query. Pertanto, tendono a ridimensionarsi in modo lineare anche se le tabelle associate hanno indici.
Potresti prendere in considerazione l'utilizzo di una funzione con valori di tabella inline, poiché vengono valutati in linea con la query e possono essere ottimizzati. Ottieni l'incapsulamento che desideri, ma le prestazioni di incollare le espressioni direttamente nell'istruzione select.
Come effetto collaterale dell'essere inline, non possono contenere alcun codice procedurale (nessuna dichiarazione @variable; set @variable =..; return). Tuttavia, possono restituire più righe e colonne.
Potresti riscrivere le tue funzioni in questo modo:
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
);
Anche la sintassi per usarli è leggermente diversa:
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)