我正在努力将一些空间搜索功能从带有 PostGIS 的 Postgres 转移到 SQL Server,我看到一些非常糟糕的性能,即使使用索引也是如此。
我的数据大约有一百万个点,我想找出哪些点在给定的形状内,所以查询看起来像这样:
DECLARE @Shape GEOMETRY = ...
SELECT * FROM PointsTable WHERE Point.STWithin(@Shape) = 1
如果我选择一个相当小的形状,有时我可以得到亚秒级的时间,但如果我的形状相当大(有时是这样),我可以得到超过 5 分钟的时间。如果我在 Postgres 中运行相同的搜索,它们总是不到一秒(事实上,几乎所有搜索都在 200 毫秒以下)。
我在我的索引上尝试了几种不同的网格大小(全部为高、全部为中等、全部为低),每个对象有不同的单元格(16、64、256),无论我做什么,时间都保持相当恒定。我想尝试更多的组合,但我什至不知道该往哪个方向走。每个对象有更多单元格?较少的?一些奇怪的网格大小组合?
我查看了我的查询计划,他们总是使用索引,这根本没有帮助。我什至尝试过不使用索引,它并没有更糟。
有没有人可以就此提供任何建议?我能找到的一切都表明“我们无法就索引给你任何建议,只是尝试一切,也许一个会奏效”,但是创建索引需要 10 分钟,盲目地这样做是浪费大量时间。
编辑:我也在微软论坛上发布了这个。以下是他们要求的一些信息:
我能得到的最好的工作指数是这个:
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
,它还不错,但仍然不擅长)。
我能够使用索引,它只是没有帮助。每个测试都是在打开“显示实际执行计划”的情况下运行的,它总是显示索引。