我有两个表名为Point,另一个名为Poly,我在Poly表中有大约400个多边形,在Point表中有大约20万个点。我想要的是找到某个多边形中有多少个点。我正在使用的查询是:
select COUNT(*) from point p
inner join Poly pl on pl.GeoDataID = 101 and p.geopoint.STIntersects(pl.Poly)=1
我还在GeoPoint和Poly Columns上创建了空间索引,这两列都是地理类型。
编辑:使用SQL Server 2008
问题:上面的查询会在大约1分钟到40秒内返回结果,这对我的情况来说太慢了,因为我想在Google地图上实时显示它们。我对这个问题的处理方法是对的吗?还是有更好的方法来实现这个目标?
答案 0 :(得分:2)
首先检查您的空间索引。您可以使用SQL语句(例如
)创建它们CREATE SPATIAL INDEX MyIndexName ON MyTable(GeomFieldName) USING GEOMETRY_GRID
WITH (
BOUNDING_BOX =(-1493907.5664457313, 6128509.51667404, -578861.3521250226, 7703103.135644257),
GRIDS =(LEVEL_1 = MEDIUM,LEVEL_2 = MEDIUM,LEVEL_3 = MEDIUM,LEVEL_4 = MEDIUM),
CELLS_PER_OBJECT = 16, PAD_INDEX = OFF, SORT_IN_TEMPDB = OFF,
DROP_EXISTING = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
要更改的关键参数是BOUNDING_BOX。这可以设置为数据的边界框,也可以设置为预期数据的最大边界框。因此,如果您的数据仅限于北美,请将边界框设置为北美而非世界范围。
您可以添加计算字段以显示http://geographika.co.uk/sql-server-spatial-sql中所述的每个要素的边界 - 然后可以使用标准查询来查看最大范围。
还要检查使用分析器来查看实际使用的索引。有时您必须强制使用WITH(INDEX(MyIndexName))语句。
SELECT *
FROM MyTable
WITH (INDEX (MyIndexName))
WHERE (geometry::Point(@x,@y,3785).STWithin(MyGeomField) = 1)
我还发现,有时用点 查询时使用空间索引会更快,所以值得尝试。
<强>替代强>
最后一个选项是在添加新记录时创建触发器,该记录在创建或更新时为其分配多边形ID。这将允许几乎即时查询您的数据。
最后
在最新的Denali SQL Server版本中,可以使用自动选项而不是手动创建空间索引。 STWithin和STIntersects显然也有性能提升。