J'ai une requête qui prend trop de temps et expire fréquemment. C'est une fonction table-valeur de recherche de code postal basée sur la proximité. Est-il possible d'indexer en fonction de la requête, de sorte qu'il n'est pas nécessaire de recalculer toutes ces valeurs à chaque fois? Le code postal et la liste des codes postaux combinés représentent plus d'un million de lignes.Indexation sur une requête
Voici la fonction de la table.
Create FUNCTION [dbo].[ZipsInRadius] (@zipCode varchar(15),
@radius int, @unit char(1))
RETURNS @areaResults TABLE(
Zip varchar (30),
City varchar (255),
St varchar (20),
Lat decimal (16,12),
Long decimal (16,12))
BEGIN
DECLARE @iStartLat decimal(16, 12)
DECLARE @iStartLong decimal(16, 12)
SELECT
@iStartLat = CAST(Latitude AS decimal(16, 12)),
@iStartLong = CAST(Longitude AS decimal(16, 12))
FROM zip
WHERE zipcode LIKE @zipCode + '%'
SELECT
@iStartLat = CAST(Latitude AS decimal(16, 12)),
@iStartLong = CAST(Longitude AS decimal(16, 12))
FROM postalcode
WHERE postalcode LIKE @zipCode + '%'
DECLARE @latRange decimal(16, 12)
DECLARE @longRange decimal(16, 12)
IF (@unit = 'K') --Get distance in kilometers
BEGIN
SELECT @LatRange =
(CAST(@radius/((6076.0/5280.0) * 60.0)
AS decimal(16, 12))) * 0.621371
SELECT @LongRange =
(@radius/(((cos(@iStartLat * pi()/180.0) * 6076.0)
/5280.0) * 60)) * 0.621371
END
ELSE --Get distance in miles (the default)
BEGIN
SELECT @LatRange = CAST(@radius/((6076.0/5280.0) * 60.0)
AS decimal(16, 12))
SELECT @LongRange =
@radius/(((cos(@iStartLat * pi()/180.0) * 6076.0)
/5280.0) * 60)
END
DECLARE @lowLatitude decimal(16, 12)
DECLARE @highLatitude decimal(16, 12)
DECLARE @lowLongitude decimal (16, 12)
DECLARE @highLongitude decimal (16, 12)
SELECT @lowLatitude = @iStartLat - @latRange
SELECT @highLatitude = @iStartLat + @latRange
SELECT @lowLongitude = @iStartLong - @longRange
SELECT @highLongitude = @iStartLong + @longRange
INSERT INTO @areaResults (zip, city, st, lat, long)
SELECT ZIPcode, CITY, STate, LATitude, LONGitude
FROM Zip Z
WHERE Z.Latitude <= @highLatitude
AND Z.Latitude >= @lowLatitude
AND Z.Longitude >= @lowLongitude
AND Z.Longitude <= @highLongitude
INSERT INTO @areaResults (zip, city, st, lat, long)
SELECT postalcode, CITY, province, LATitude, LONGitude
FROM postalcode z
WHERE Z.Latitude <= @highLatitude
AND Z.Latitude >= @lowLatitude
AND Z.Longitude >= @lowLongitude
AND Z.Longitude <= @highLongitude
RETURN
END
grâce ... J'ai ajouté les index, mais je encore des problèmes. le zip en question retourne effectivement 98000 lignes (son à Toronto), et prend 41 secondes à courir ... – Shawn
malade hve pour essayer la chose décimale, il semble que les deux tables ont des types différents, c'est probablement faire une tonne de conversions – Shawn
Finalement, j'ai juste ajouté un index sur le zip et puis interne le rejoindre sur la table que je cherchais en premier. il a réduit la fonction de valeur de table par beaucoup – Shawn