Update : Since writing this post we decided to migrate our geospatial data to an ElasticSearch database, which yielded better results.
I'm new to SQL and I need help to optimize a spatial query so that it runs under in under 2 seconds. We have already tried some suggestions found on various sites (More on that below).
We have a table [Id, Geometry] of about 300,000 geometric shapes of varying sizes and complexity, stored as geometry data types. We have created a spatial index for the Geometry using the code snippet below.
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.
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 details:
Spatial index seek details:
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.)?
How can the execution time be shortened overall, or is 7-10 seconds what you can expect for this kind of query?
Each of these saved roughly a few seconds.
STIntersect()
to Filter()
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.) SimpleGeometry
which contains the bounding boxes of all the geometry objects from the Geometry
column. Created a new SimpleGeometry
spatial index and used SimpleGeometry
for the lookup instead of 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.