0

SQLServerのGeographyデータ型を使用して郵便番号を使用している距離の人々に基づいて照合するクエリを作成しています。99%ありますが、2つの問題があります。現時点では、これはzip、都市、州で検索しますが、[u.username]でも実際に一致させる必要があります。「ORUsernameLIKE@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

これにより、約1秒で300人を超えるユーザーにいくつかの異なるフィールドでページングとクエリを実行できます。これは素晴らしいことではありませんが、今のところは許容範囲です。

于 2011-11-12T14:33:45.920 に答える