我有一个表格点有一个点类型为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);
表现仍然不可接受。
答案 0 :(得分:2)
微软自己在MSDN上的文章提出了一些改进措施,可以确保“最近邻”查询使用空间索引。对我来说主要的一个问题是缺乏在WHERE子句中使用STDistance来限制距离(没有它就不能以任何方式过滤)。
尝试应用它,看看是否可以提高性能。如果没有参考文章本身的进一步提示。
修改强>
首先,您可以按如下方式简化在查询中创建点的过程:
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))提示。如果仍然无效,您可以上传查询执行计划吗?