¿Por qué las funciones con valores escalares parecen hacer que las consultas se ejecuten de forma acumulativamente más lenta cuanto más veces en sucesión se utilizan?¿Por qué las funciones de valor escalar de SQL Server se vuelven más lentas?
Tengo esta tabla que fue construida con datos comprados de un tercero.
He recortado algunas cosas para hacer que esta publicación sea más corta ... pero solo para que tenga la idea de cómo se configuran las cosas.
CREATE TABLE [dbo].[GIS_Location](
[ID] [int] IDENTITY(1,1) NOT NULL, --PK
[Lat] [int] NOT NULL,
[Lon] [int] NOT NULL,
[Postal_Code] [varchar](7) NOT NULL,
[State] [char](2) NOT NULL,
[City] [varchar](30) NOT NULL,
[Country] [char](3) NOT NULL,
CREATE TABLE [dbo].[Address_Location](
[ID] [int] IDENTITY(1,1) NOT NULL, --PK
[Address_Type_ID] [int] NULL,
[Location] [varchar](100) NOT NULL,
[State] [char](2) NOT NULL,
[City] [varchar](30) NOT NULL,
[Postal_Code] [varchar](10) NOT NULL,
[Postal_Extension] [varchar](10) NULL,
[Country_Code] [varchar](10) NULL,
Luego tengo dos funciones que buscan LAT y LON.
CREATE FUNCTION [dbo].[usf_GIS_GET_LAT]
(
@City VARCHAR(30),
@State CHAR(2)
)
RETURNS INT
WITH EXECUTE AS CALLER
AS
BEGIN
DECLARE @LAT INT
SET @LAT = (SELECT TOP 1 LAT FROM GIS_Location WITH(NOLOCK) WHERE [State] = @State AND [City] = @City)
RETURN @LAT
END
CREATE FUNCTION [dbo].[usf_GIS_GET_LON]
(
@City VARCHAR(30),
@State CHAR(2)
)
RETURNS INT
WITH EXECUTE AS CALLER
AS
BEGIN
DECLARE @LON INT
SET @LON = (SELECT TOP 1 LON FROM GIS_Location WITH(NOLOCK) WHERE [State] = @State AND [City] = @City)
RETURN @LON
END
Cuando ejecuto el siguiente ...
SET STATISTICS TIME ON
SELECT
dbo.usf_GIS_GET_LAT(City,[State]) AS Lat,
dbo.usf_GIS_GET_LON(City,[State]) AS Lon
FROM
Address_Location WITH(NOLOCK)
WHERE
ID IN (SELECT TOP 100 ID FROM Address_Location WITH(NOLOCK) ORDER BY ID DESC)
SET STATISTICS TIME OFF
100 ~ = 8 ms, 200 ~ = 32 ms, 400 ~ = 876 ms
--Editar sentimos que debería han sido más claros. No estoy buscando sintonizar la consulta mencionada anteriormente. Esto es solo una muestra para mostrar que el tiempo de ejecución se vuelve más lento cuanto más registros atraviesa. En la aplicación del mundo real, las funciones se utilizan como parte de una cláusula where para crear un radio alrededor de una ciudad y un estado para incluir todos los registros en esa región.
no suba espolvorear los consejos NOLOCK en muestras que no lo necesitan en SO, las cosas de NOLOCK realmente no tienen nada que ver con esta pregunta. –
si no puede deshacerse de las funciones en la "consulta real", entonces siempre será muy lento. Da un mejor ejemplo, con las funciones que se utilizan en WHERE y podemos darte ideas sobre eso ... –