2012-08-29 100 views
4

我有一个表格(表格2),其中包含一些存储为地理数据类型的区域(多边形)。该表包含1529行。在另一个表格(Table1)中,我有约。 22000行,每行都有一个X/Y,我可以从中创建存储在地理栏中的点。SQL Server空间查询优化

我需要做一个空间连接来找出每个点属于哪个区域。我在两个表上都创建了空间索引,但我认为查询太慢了。现在,它需要约72秒,以使加入的是这样的:

SELECT ... 
FROM [DatabaseA].dbo.Table1 t1 
INNER JOIN [DatabaseB].dbo.Table2 t2 ON t1.Geo.STIntersects(t2.Geo) = 1 
WHERE t2.ObjectTypeId = 1 AND t2.CompanyId = 3 

请注意,这两个表在不同的数据库,但在同一台服务器上。

在创建空间索引之前,查询速度非常慢,我可以看到正在使用该索引。但是,在table2上创建索引不会影响性能,只有table1上的索引会提供更好的性能。两个指数具有较高的水平格栅

当我看的执行计划,我注意到一个筛选一部分花费的时间71%:

CASE WHEN [Expr1015]>(2) THEN CASE WHEN [Expr1016]=[Expr1017] THEN (1) ELSE (0) END ELSE [DatabaseA].[dbo].[Table1].[Geo] as [t].[Geo].STIntersects([DatabaseB].[dbo].[Table2].[Geo] as [g].[Geo]) END=(1) 

所以,我的问题是:

若本查询需要这么久? 我应该使用其他网格尺寸吗? 那个过滤器表达式是什么意思?

有没有人有提示优化呢?

+0

与许多问题非常相似,请参阅我对此的回应:http:// stackoverflow。COM /问题/ 7655408/SQL的空间加入/ 7672934#7672934 – CatchingMonkey

+0

SQL Server 2008或2012? – AakashM

+0

@CatchingMonkey:正如我写的,该指数已被使用,因此增加了一丝不上的表现有所帮助。 – user1632306

回答

1

简而言之,您使用参数t2.Geo调用函数,该函数必须由函数对t2中的所有值进行求值,其中t2.ObjecttypeId = 1且t2.CompanyId = 3。表t2并没有真正的帮助,因为它不能使用这些预先计算的索引值。相反,它必须首先在t2中的所有值上运行函数t1.Geo.STIntersects(t2.Geo) - 它们与预先计算的索引值几乎没有关系。

如果速度是您的目标并且您有存储空间,那么您可以创建第三个表格,其中包含t1.Geo.STIntersects(t2.Geo)的每种组合的预计算结果。然后,您可以将t1和t2连接到第三个表中的预计算值,该表应该能够产生几乎即时的查询结果(对于包含1,529和22,000条记录的源表)。

如果t1和t2中的数据是相对静态的,您可以手动重新运行一个查询来更新第三个表中的数据。如果频繁更改,则可以通过更新,插入和删除到t1和t2的触发器自动维护,或者可以将更新,插入和删除操作包装到更新预计算表的存储过程中。

+0

我与大空间数据集(10K +记录)的工作越多,我看到需要已经计算表中存储任何关系和属性我想找到。空间索引可以让您在很短的时间内完成很多工作,但对于有用户等待查询结果的OLTP系统来说,这并不实际。至少当你有很多数据时,空间通常就是这样。确定相交点,最近的邻居等,并将其存储在一个表中。根据需要经常刷新。 – radpin

2

我有类似的问题。我有2000点和85000多边形。我需要匹配具有匹配多边形的点。最初那个查询需要8个小时。

SELECT Item.Name, Polygons.Name 
FROM dbo.Geofence AS Polygons 
JOIN dbo.ItemLocation AS Points 
ON Polygons.GeoFence.STIntersects(Points.GeoLocation) = 1 

问题是点表具有非聚集索引。添加聚集索引将时间缩短为12秒。

添加空间索引(下面的代码)将时间减少到1秒。我还在积分表中添加了一个。

CREATE SPATIAL INDEX [SpatialIndex-Polygons] ON dbo.Polygons 
(
    [Geofence] 
)USING GEOGRAPHY_GRID 
WITH (GRIDS =(LEVEL_1 = MEDIUM,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = MEDIUM), 
CELLS_PER_OBJECT = 16, PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]