Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Pourquoi les fonctions à valeur scalaire SQL Server deviennent-elles plus lentes ?

Dans la plupart des cas, il est préférable d'éviter les fonctions à valeur scalaire qui font référence à des tables car (comme d'autres l'ont dit) ce sont essentiellement des boîtes noires qui doivent être exécutées une fois pour chaque ligne et ne peuvent pas être optimisées par le moteur de plan de requête. Par conséquent, ils ont tendance à évoluer de manière linéaire même si les tables associées ont des index.

Vous pouvez envisager d'utiliser une fonction inline-table-value, car elles sont évaluées en ligne avec la requête et peuvent être optimisées. Vous obtenez l'encapsulation que vous voulez, mais la performance de coller les expressions directement dans l'instruction select.

En tant qu'effet secondaire d'être en ligne, ils ne peuvent contenir aucun code procédural (pas de déclaration de @variable; set @variable =..; retour). Cependant, ils peuvent renvoyer plusieurs lignes et colonnes.

Vous pourriez réécrire vos fonctions comme ceci :

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
);

La syntaxe pour les utiliser est également un peu différente :

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)