Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Warum werden skalare Funktionen von SQL Server langsamer?

In den meisten Fällen ist es am besten, Skalarwertfunktionen zu vermeiden, die auf Tabellen verweisen, da es sich (wie andere bereits sagten) im Grunde genommen um Black Boxes handelt, die einmal für jede Zeile ausgeführt werden müssen und nicht von der Abfrageplan-Engine optimiert werden können. Daher neigen sie dazu, linear zu skalieren, selbst wenn die zugehörigen Tabellen Indizes haben.

Möglicherweise möchten Sie die Verwendung einer Inline-Tabellenwertfunktion in Betracht ziehen, da sie inline mit der Abfrage ausgewertet werden und optimiert werden können. Sie erhalten die gewünschte Kapselung, aber die Leistung beim Einfügen der Ausdrücke direkt in die Select-Anweisung.

Als Nebeneffekt der Einbettung können sie keinen prozeduralen Code enthalten (kein @variable deklarieren; @variable =.. setzen; return). Sie können jedoch mehrere Zeilen und Spalten zurückgeben.

Sie könnten Ihre Funktionen etwa so umschreiben:

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

Die Syntax, um sie zu verwenden, ist ebenfalls etwas anders:

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)