【发布时间】:2011-03-29 01:29:12
【问题描述】:
我正在努力将一些空间搜索功能从带有 PostGIS 的 Postgres 转移到 SQL Server,我看到一些非常糟糕的性能,即使使用索引也是如此。
我的数据大约有一百万个点,我想找出哪些点在给定的形状内,所以查询看起来像这样:
DECLARE @Shape GEOMETRY = ...
SELECT * FROM PointsTable WHERE Point.STWithin(@Shape) = 1
如果我选择一个相当小的形状,我有时可以得到亚秒级的时间,但如果我的形状相当大(有时是这样),我可以得到超过 5 分钟的时间。如果我在 Postgres 中运行相同的搜索,它们总是不到一秒(事实上,几乎所有搜索都不到 200 毫秒)。
我在索引上尝试了几种不同的网格大小(全部为高、全部为中等、全部为低),每个对象有不同的单元格(16、64、256),无论我做什么,时间都保持相当稳定。我想尝试更多的组合,但我什至不知道该往哪个方向走。每个对象有更多单元格?较少的?一些奇怪的网格大小组合?
我查看了我的查询计划,他们一直在使用索引,但这根本没有帮助。我什至尝试过不使用索引,也没有差多少。
有没有人可以就此提供任何建议?我能找到的所有内容都表明“我们无法为您提供任何关于索引的建议,只需尝试一切,也许一个会奏效”,但创建索引需要 10 分钟,盲目地这样做是浪费大量时间。
编辑: 我也在a Microsoft forum 上发布了这个。以下是他们要求的一些信息:
我能得到的最好的工作索引是这个:
CREATE SPATIAL INDEX MapTesting_Location_Medium_Medium_Medium_Medium_16_NDX
ON MapTesting (Location)
USING GEOMETRY_GRID
WITH (
BOUNDING_BOX = ( -- The extent of our data, data is clustered in cities, but this is about as small as the index can be without missing thousands of points
XMIN = -12135832,
YMIN = 4433884,
XMAX = -11296439,
YMAX = 5443645),
GRIDS = (
LEVEL_1 = MEDIUM,
LEVEL_2 = MEDIUM,
LEVEL_3 = MEDIUM,
LEVEL_4 = MEDIUM),
CELLS_PER_OBJECT = 256 -- This was set to 16 but it was much slower
)
我在使用索引时遇到了一些问题,但这次不同。
对于这些测试,我对每个索引使用 WITH(INDEX(...)) 子句进行了测试搜索(我的原始帖子中列出的那个)(测试网格大小和每个对象的单元格的各种设置),还有一个没有任何提示。我还使用每个索引和相同的搜索形状运行 sp_help_spatial_geometry_index。上面列出的索引运行速度最快,并且在 sp_help_spatial_geometry_index 中也被列为效率最高的。
运行搜索时,我会得到以下统计信息:
(1 row(s) affected)
Table 'MapTesting'. Scan count 0, logical reads 361142, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'extended_index_592590491_384009'. Scan count 1827, logical reads 8041, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 6735 ms, elapsed time = 13499 ms.
我也尝试使用随机点作为数据(因为我无法提供我们的真实数据),但事实证明这种搜索对于随机数据非常快。这使我们相信我们的问题是网格系统如何处理我们的数据。
我们的数据是整个州的地址,因此有一些非常高密度的区域,但大多是稀疏数据。我认为问题在于网格大小的设置对两者都不起作用。网格设置为HIGH,索引在低密度区域返回太多单元格,而网格设置为LOW,网格在高密度区域无用(MEDIUM,还不错,但仍然也不擅长)。
我能够得到使用的索引,只是没有帮助。每个测试都是在打开“显示实际执行计划”的情况下运行的,它总是显示索引。
【问题讨论】:
-
+1:我也想知道。
-
您的百万点数据是存储为几何(平面、欧几里得空间)还是地理(圆形、土形坐标)?如果您正在混合几何和地理,您将引入转换数学的性能影响。
-
@Mwalker,都是几何图形,我不认为你可以混合和匹配它们。
-
感谢您对 CELLS_PER_OBJECT 的评论。我使用 CELLS_PER_OBJECT = 16 和级别 = MEDIUM 获得了 6.8 秒,我将 CELLS_PER_OBJECT 更改为 256 和级别 = HIGH,时间下降到 2.8 秒 :-)
标签: sql-server sql-server-2008 geospatial spatial-index