Reputation: 1066
I have a SQL Server table with geographical points of type [latitude, longitude]. Currently, I have only few points, however, over time, I expect my table to grow significantly.
Later, I will need to query my table by proximity to another point. Is there any standardized way to do this efficiently? Some kind of geospatial index for example? What are your best practices?
The query I will need is going to look like this in pseudocode:
-- lat0, lng0 and radius0 are search parameters
-- distance() is function which computes distance between two points
SELECT id, lat, lng
FROM myTable
WHERE distance(lat, lng, lat0, lng0) < radius0
Upvotes: 0
Views: 325
Reputation: 3760
To add to alroc's answer, you can alternatively create a computed persisted column with an index.
ALTER TABLE my_table ADD geo AS GEOGRAPHY::Point (
latitude
,longitude
,4326
) persisted;
CREATE spatial INDEX SI_my_table__geo ON my_table (geo);
SELECT TOP 5 @point.STDistance(geo) as distance_meters
,id
,location_name
,latitude
,longitude
FROM my_table;
Upvotes: 2
Reputation: 28154
As marc_s mentioned, SQL Server 2008+ has geospatial types which you can use. If you want to keep latitude & longitude separate on myTable
but also have a geospatial column which represents those coordinates, you can use a computed column (but be aware of possible performance issues resulting from it) so you don't have duplicated data on the table itself.
[latlong] AS ([geography]::Point([Latitude],[Longitude],(4326)))
Then, to find any points within a radius of another point, you can use the STDistance
method of the geography
type.
declare @radius int = 100000;
declare @p1 geography = geography::STGeomFromText('POINT(-122.33365 47.612033)',4326);
select * from myTable where @p1.STDistance(latlong) <= @radius;
Note that distances are calculated in meters.
Upvotes: 2