Warum scheinen Scalar-bewertete Funktionen dazu zu führen, dass Abfragen kumulativ langsamer ausgeführt werden, je öfter sie nacheinander verwendet werden?Warum werden Skalarwertfunktionen von SQL Server langsamer?
Ich habe diese Tabelle, die mit Daten von einer Drittpartei erworben wurde.
Ich habe einige Sachen zurechtgeschnitten, um diesen Beitrag kürzer zu machen ... aber nur damit Sie die Idee bekommen, wie die Dinge aufgebaut sind.
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,
Dann habe ich zwei Funktionen, die LAT und LON nachschlagen.
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
Wenn ich laufen die folgenden ...
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
--edit Leider sollte ich waren klarer. Ich möchte die oben aufgelistete Abfrage nicht optimieren. Dies ist nur ein Beispiel, um zu zeigen, dass die Ausführungszeit umso langsamer wird, je mehr Datensätze durchgebrochen werden. In der realen Weltanwendung werden die Funktionen als Teil einer where-Klausel verwendet, um einen Radius um eine Stadt und einen Bundesstaat herum zu erstellen, um alle Datensätze mit in diese Region aufzunehmen.
nicht die NOLOCK Hinweise Lassen bestreuen auf Samples, die es in SO nicht brauchen, hat das NOLOCK-Zeug wirklich nichts mit dieser Frage zu tun. –
Wenn Sie die Funktionen in der "echten Abfrage" nicht loswerden können, wird es immer sehr langsam sein. Geben Sie ein besseres Beispiel, mit den Funktionen, die in der WHERE verwendet werden, und wir können Ihnen dazu Ideen geben ... –