Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Por que as funções com valor escalar do SQL Server ficam mais lentas?


Na maioria dos casos, é melhor evitar funções de valor escalar que referenciam tabelas porque (como outros disseram) elas são basicamente caixas pretas que precisam ser executadas uma vez para cada linha e não podem ser otimizadas pelo mecanismo de plano de consulta. Portanto, eles tendem a escalar linearmente mesmo se as tabelas associadas tiverem índices.

Você pode querer considerar o uso de uma função com valor de tabela embutida, pois elas são avaliadas em linha com a consulta e podem ser otimizadas. Você obtém o encapsulamento desejado, mas o desempenho de colar as expressões diretamente na instrução select.

Como efeito colateral de serem embutidos, eles não podem conter nenhum código de procedimento (não declare @variable; set @variable =..; return). No entanto, eles podem retornar várias linhas e colunas.

Você poderia reescrever suas funções mais ou menos assim:
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
);

A sintaxe para usá-los também é um pouco diferente:
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)