从地理列中搜索附近的点

Bah*_*mut 3 sql geolocation sql-server-2008-r2 sqlgeography

我的表中有一个带有空间索引的地理类型列.如何在使用索引来提高性能的同时选择在给定纬度/经度的X米范围内的前N行?

Pad*_*ddy 7

当你说"在利用指数时" - 你的意思是什么?

我刚开始(今天)尝试使用SQL 2012及其Geography数据类型,但可能以下内容很有用 - 我确实意识到你正在使用2008-R2

创建一些数据:

CREATE TABLE SpatialTable 
    ( id int IDENTITY (1,1) PRIMARY KEY,
    GeogCol1 geography, 
    GeogCol2 AS GeogCol1.STAsText() );
GO

INSERT INTO SpatialTable (GeogCol1)
VALUES 
(geography::STGeomFromText('POINT(-122.360 47.656)',4326)),
(geography::STGeomFromText('POINT(-122.343 47.656)',4326)),
(geography::STGeomFromText('POINT(-122.358 47.660)',4326)),
(geography::STGeomFromText('POINT(-122.348 47.649)',4326)),
(geography::STGeomFromText('POINT(-122.348 47.658)',4326)),
(geography::STGeomFromText('POINT(-122.358 47.653)',4326))
Run Code Online (Sandbox Code Playgroud)

创建索引:

CREATE SPATIAL INDEX Spatialindex ON SpatialTable ( GeogCol1 ) USING GEOGRAPHY_GRID 
WITH (
    GRIDS =(LEVEL_1 = MEDIUM,LEVEL_2 = MEDIUM,LEVEL_3 = MEDIUM,LEVEL_4 = MEDIUM),
    CELLS_PER_OBJECT = 16, PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF,
    DROP_EXISTING = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON
)
Run Code Online (Sandbox Code Playgroud)

定义兴趣点:

DECLARE @g geography;
SET @g = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326);
Run Code Online (Sandbox Code Playgroud)

找到距离最近的2,距离点750米

SELECT TOP 2
        @g.STDistance(st.GeogCol1) AS [DistanceFromPoint (in meters)] 
    ,   st.GeogCol2
    ,   st.id
FROM    SpatialTable st WITH(INDEX(SpatialIndex))
WHERE   @g.STDistance(st.GeogCol1) <= 750
ORDER BY @g.STDistance(st.GeogCol1) ASC
Run Code Online (Sandbox Code Playgroud)

得到:

DistanceFromPoint (in meters) GeogCol2                 id
----------------------------- ------------------------ -----------
234.715604015178              POINT (-122.348 47.649)  4
711.760044795868              POINT (-122.358 47.653)  6
Run Code Online (Sandbox Code Playgroud)

SQL Execution Plan建议正在使用的索引,这个网站提示返回的距离是正确的

如果这不是您需要的,请告诉我,我正在尝试自己学习,所以任何修改都是好的!

***编辑****我添加了一个索引表提示,强制查询使用索引(根据此MSDN帖子).该链接解释了索引可能最初未使用,因为SQL确定不使用索引会更快.上面我的示例的执行计划显示使用/不使用索引的97%/ 3%分割,因此在这个实例中,SQL优化器有正确的想法.

为什么在使用索引时查询速度较慢似乎是SO上众多博客帖子和问题的主题.