简体   繁体   English

需要帮助来优化可能错误的空间SQL查询

[英]Need help to optimize potentially erroneous spatial SQL query

Update : Since writing this post we decided to migrate our geospatial data to an ElasticSearch database, which yielded better results. 更新 :自撰写本文以来,我们决定将我们的地理空间数据迁移到ElasticSearch数据库,从而产生更好的结果。

I'm new to SQL and I need help to optimize a spatial query so that it runs under in under 2 seconds. 我是SQL的新手,我需要帮助来优化空间查询,以便它在2秒内运行。 We have already tried some suggestions found on various sites (More on that below). 我们已经在各个网站上尝试了一些建议(更多内容见下文)。

Background 背景

We have a table [Id, Geometry] of about 300,000 geometric shapes of varying sizes and complexity, stored as geometry data types. 我们有一个表[Id,Geometry],大约300,000个不同大小和复杂度的几何形状,存储为几何数据类型。 We have created a spatial index for the Geometry using the code snippet below. 我们使用下面的代码片段为Geometry创建了一个空间索引。

CREATE SPATIAL INDEX [IX_Geometry_Spatial]
ON [dbo].[Geometries] ([Geometry]) USING  GEOMETRY_AUTO_GRID 
WITH  (
        BOUNDING_BOX = (XMAX = 24.43359375, XMIN = 10.810546875, YMAX = 69.2249968541159, YMIN = 55.2791152920156)
      );

What we want is to find all the geometric shapes that intersects with an input geometric shape. 我们想要的是找到与输入几何形状相交的所有几何形状。 This is done by using the following query. 这是通过使用以下查询完成的。

DECLARE @g geometry;  
SET @g = geometry::STGeomFromText('POLYGON ((x0 y0, ...))', 4326); -- A Worst Case Polygon containing 1442 data points

SELECT Count(Id)
FROM Geometries
WHERE Geometries.Geometry.Filter(@g.Reduce(.25)) = 1

For some worst case input geometric shapes (large, complex polygons) this execution takes about 7-10 seconds. 对于某些最坏情况的输入几何形状(大的,复杂的多边形),这种执行大约需要7-10秒。

This is the execution plan for the query: 这是查询的执行计划: 在此输入图像描述

We can see that we hit the spatial index, but the most expensive operation is the clustered index seek (Clustered) 我们可以看到我们击中了空间索引,但最昂贵的操作是clustered index seek (Clustered)

Clustered index seek details: 聚集索引寻求详细信息:

在此输入图像描述

Spatial index seek details: 空间索引寻求细节:

在此输入图像描述

Questions 问题

Shouldn't the heavy lifting be done by the spatial index, not the clustered index? 不应该通过空间索引而不是聚集索引来完成繁重的工作吗?

Can the query be improved by changing settings for the spatial index? 可以通过更改空间索引的设置来改进查询吗? What settings should we use (for GRIDS, CELLS_PER_OBJECT, etc.)? 我们应该使用什么设置(对于GRIDS,CELLS_PER_OBJECT等)?

How can the execution time be shortened overall, or is 7-10 seconds what you can expect for this kind of query? 如何将整个执行时间缩短,或者这种查询可以达到7-10秒?

What we have tried, that helped 我们尝试了什么,这有帮助

Each of these saved roughly a few seconds. 每个都节省了大约几秒钟。

  • Checked for index fragmentation, and rebuilt indexes. 检查索引碎片和重建索引。
  • Switched intersection method from STIntersect() to Filter() STIntersect()Filter()交换方法
  • Reduced the input geometry with Reduce(.25) . 使用Reduce(.25)减少输入几何Reduce(.25) This Reduces the geometry from 1442 data points to 7. (If we decide to use this, it will have to be dynamic for different inputs, but that's another issue.) 这将几何从1442个数据点减少到7.(如果我们决定使用它,它必须是不同输入的动态,但这是另一个问题。)
  • Introduced a new table column SimpleGeometry which contains the bounding boxes of all the geometry objects from the Geometry column. 引入了一个新的表格列SimpleGeometry ,其中包含Geometry列中所有几何对象的边界框。 Created a new SimpleGeometry spatial index and used SimpleGeometry for the lookup instead of Geometry . 创建了一个新的SimpleGeometry空间索引,并使用SimpleGeometry进行查找而不是Geometry (Not in use in query example.) (在查询示例中未使用。)

What if you did the calculation each time you added a new shape, then stored just the intersections in a table? 如果您在每次添加新形状时进行计算,然后仅将交叉点存储在表格中,该怎么办? Now your query is instantaneous. 现在您的查询是即时的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM