选择最近的点sql server空间

时间:2016-07-14 14:54:46

标签: sql-server tsql sql-server-2014 spatial spatial-index

我有一个表格点有一个点类型为GEOGRAPHY。我正在运行此代码以获得最接近的点:

In [68]:
array1 = np.random.randn(3,3)
array2 = np.random.randn(3,3)
​
df1 = pd.DataFrame(array1, columns=list('ABC'))
df2 = pd.DataFrame(array2, columns=list('ABC'))
​
df = pd.concat([df1, df2], ignore_index=True)
df

Out[68]:
          A         B         C
0 -0.091094  0.460133 -0.548937
1 -0.839469 -1.354138 -0.823666
2  0.088581 -1.142542 -1.746608
3  0.067320  1.014533 -1.294371
4  2.094135  0.622129  1.203257
5  0.415768 -0.467081 -0.740371

Points表有这个索引:

DECLARE @Wgs84Longitude FLOAT;
DECLARE @Wgs84Latitude FLOAT;

DECLARE @Point GEOGRAPHY = Geography::STPointFromText(N'POINT('
                                           + CAST(@Wgs84Longitude AS NVARCHAR(MAX))
                                           + N' '
                                           + CAST(@Wgs84Latitude AS NVARCHAR(MAX))
                                           + N')', 4326);

SELECT 
    TOP 1
    *
FROM Points
ORDER BY @Point.STDistance(Point) ASC;

不幸的是,查询速度很慢。有什么我可以改进以使其更快(索引和/或查询明智)?

PS:

我也玩过一些这样的东西:

CREATE SPATIAL INDEX SpatialIndex ON Points (Point);

表现仍然不可接受。

1 个答案:

答案 0 :(得分:2)

微软自己在MSDN上的文章提出了一些改进措施,可以确保“最近邻”查询使用空间索引。对我来说主要的一个问题是缺乏在WHERE子句中使用STDistance来限制距离(没有它就不能以任何方式过滤)。

尝试应用它,看看是否可以提高性能。如果没有参考文章本身的进一步提示。

MSDN Nearest Neighbor

修改

首先,您可以按如下方式简化在查询中创建点的过程:

DECLARE @Point GEOGRAPHY = GEOGRAPHY::Point(@latitude, @longitude, @srid);

其次,它可能不会有所作为,但你可以将你的空间索引声明为最大16个单元格的HHHH(你可以选择一个)。在一天结束时,作为一个奇点,它只会在最低级别的索引中有一条记录,但这取决于你是否要在列中混合空间数据类型。

第三,我已经进行了多次测试,您应该可以轻松获得一秒钟的结果。我使用了以下查询:

SELECT TOP 1
*
FROM
Points P
WHERE P.Point.STDistance(@Point) < (50 * 1609.344) -- 50 miles
ORDER BY P.Point.STDistance(@Point)

我的结果比1秒快得多。如果我省略了WHERE子句,则时间会慢大约1500%(随着数据集大小的增加/减少)。但这比你10-12秒的结果还要快得多。

您可以验证您的空间索引是否正常工作?如果没有,请尝试使用WITH(INDEX(SpatialIndex))提示。如果仍然无效,您可以上传查询执行计划吗?