sql >> Database >  >> RDS >> Sqlserver

Waarom worden SQL Server Scalaire functies langzamer?

In de meeste gevallen is het het beste om scalaire functies te vermijden die verwijzen naar tabellen, omdat het (zoals anderen al zeiden) in feite zwarte dozen zijn die één keer voor elke rij moeten worden uitgevoerd en niet kunnen worden geoptimaliseerd door de queryplan-engine. Daarom hebben ze de neiging om lineair te schalen, zelfs als de bijbehorende tabellen indexen hebben.

U kunt overwegen een functie met inline-tabelwaarde te gebruiken, omdat deze inline met de query worden geëvalueerd en kunnen worden geoptimaliseerd. U krijgt de gewenste inkapseling, maar de prestatie van het plakken van de uitdrukkingen in de select-instructie.

Als neveneffect van het feit dat ze inline zijn, kunnen ze geen procedurele code bevatten (no declare @variable; set @variable =..; return). Ze kunnen echter meerdere rijen en kolommen retourneren.

Je zou je functies ongeveer als volgt kunnen herschrijven:

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

De syntaxis om ze te gebruiken is ook een beetje 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)


  1. SQL-injectie in Node.js voorkomen

  2. Docker PGMASTER PostgreSQL-versie-update

  3. Gebruik variabele ingesteld door psql meta-commando in DO-blok

  4. Hoe de beginwaarde en automatische verhoging in MySQL in te stellen?