Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Perché le funzioni con valori scalari di SQL Server diventano più lente?

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)