0

我正在使用 SQL Server 中的 Geography 数据类型创建一个查询,以根据距离人们使用邮政编码进行匹配。我在那里有 99%,但我有两个问题。目前,此搜索按 zip、城市和州进行,但我还需要在 [u.username] 上进行匹配。我无法获得添加“OR Username LIKE @Name”的语法。其次,性能不是很好。有来自美国各地的 21 个测试用户,查询需要 4 秒。

有没有办法加快速度并添加额外的搜索参数。到目前为止我有这个:

DECLARE @miles [float] = 10000;
DECLARE @myposition geography;
SELECT @myposition = GeoLocation FROM ZipCodes
WHERE Zip LIKE '11204';

SELECT z.*,z.GeoLocation.STDistance(@myposition) AS Distance INTO #HASHTABLE FROM ZipCodes z
WHERE z.GeoLocation.STDistance(@myposition) <= (@miles*1609.344)
ORDER BY Distance asc

;WITH Results_CTE AS (SELECT u.*,z.GeoLocation.STDistance(@myposition) AS Distance, ROW_NUMBER() OVER (ORDER BY z.GeoLocation.STDistance(@myposition)) AS RowNum
FROM Users u INNER JOIN ZipCodes z ON u.PostCode = z.Zip
WHERE u.PostCode in (SELECT Zip from #hashtable) OR u.City in (SELECT City from #hashtable) 
) SELECT * FROM Results_CTE WHERE RowNum > 0 
DROP TABLE #Hashtable
4

2 回答 2

1

您是否声明了任何索引?我将放弃临时表并编写以下查询,还添加一些索引:ZipCodes 表(GeoLocation 列上的空间索引)和 users 表(City 和 Zip 列上)。

DECLARE @miles [float] = 10000;
DECLARE @myposition geography;
SELECT @myposition = GeoLocation FROM ZipCodes
WHERE Zip LIKE '11204';

SELECT u.*,z.GeoLocation.STDistance(@myposition) as Distance from Users u
INNER JOIN ZipCodes z ON u.PostCode = z.Zip
WHERE
    z.GeoLocation.STDistance(@myposition) <= (@miles*1609.344)
AND
    u.Username LIKE '%'+@Name+'%'

UNION

SELECT u.*,z.GeoLocation.STDistance(@myposition) as Distance from Users u
INNER JOIN ZipCodes z ON u.City = z.City
WHERE
    z.GeoLocation.STDistance(@myposition) <= (@miles*1609.344)
AND
    u.Username LIKE '%'+@Name+'%'

ORDER BY
    z.GeoLocation.STDistance(@myposition)
于 2011-11-06T20:10:45.943 回答
1

谢谢@cipx,但我发现您的建议实际上返回了重复项。在用新的眼光看了这个之后,我似乎有办法用 AND 或 OR 搜索多个字段。

DECLARE @miles [float] = 100;
DECLARE @myposition geography;
SELECT @myposition = GeoLocation FROM ZipCodes
WHERE Zip LIKE '28790'; --OR city like 'brooklyn';--'11204';

SELECT z.*,z.GeoLocation.STDistance(@myposition) AS Distance INTO #HASHTABLE FROM ZipCodes z
WHERE z.GeoLocation.STDistance(@myposition) <= (@miles*1609.344)
ORDER BY Distance asc

;WITH Results_CTE AS (SELECT u.*,z.GeoLocation.STDistance(@myposition) AS Distance, ROW_NUMBER() OVER (ORDER BY z.GeoLocation.STDistance(@myposition), userid) AS RowNum
FROM Users u INNER JOIN ZipCodes z ON u.PostCode = z.Zip
WHERE 
-- Using zip code and distance
-- u.PostCode in (SELECT Zip from #hashtable) 

-- using a link table to find users skilled in wrestling
-- OR UserID IN (SELECT UserID from UserSkills us INNER JOIN Skills s ON us.SkillID = s.SkillID WHERE s.Name LIKE 'wrestlin%') 

-- scalar properties of the UserProfiles table
-- DisplayName like 'johnny%'
) SELECT * FROM Results_CTE WHERE RowNum > 0 
DROP TABLE #Hashtable

这使我可以在大约一秒钟内对几个不同字段的 300 多个用户进行分页和查询,这不是很好,但现在可以接受。

于 2011-11-12T14:33:45.920 回答