Performance issue iterating FeatureQueryResult

323
6
a month ago
MarcHillman
New Contributor III

I have a VB.net application that is using QueryFeaturesAsync to retrieve a FeatureQueryResult  from a shapefile. It typically returns between 2 and 12 features. When I iterate through the result (for each fragment in FeatureQueryResult ) it takes forever - about 7-20 seconds.

What I'm trying to achieve is to calculate the Extent of the FeatureQueryResult . I do this by iterating though the FeatureQueryResult  and doing a CombineExtents for each individual result. Is there a way to do this without iterating? Why is it so slow?

0 Kudos
6 Replies
Nicholas-Furness
Esri Regular Contributor

Hi Marc,

7-20 seconds for a handful of features surprises me. Some thoughts:

  • I assume the shapefile is not on a network share. Is that correct?
  • Is this a spatial query, or just an attribute query?
  • Are the features in the shapefile complicated polygons or polylines?

You could try calling QueryExtentAsync and see if that improves things. If you also need attributes from the features, you could make a separate query and specify not to return geometries.

Let us know if any of those things help.

Are you able to share the shapefile? You can DM me to share that if you are able to.

MarcHillman
New Contributor III

1. Shapefile is on local harddrive.

2. Spatial query (returning geometry). Elapsed time is only 1-2 sec, which seems reasonable.

3. Features are "complicated". All polygons between 1 and 40 of them.

I was unaware of QueryExtentAsync. Using that, rather than iterating through the geometry, reduces the time from 10s to 3s. Still a little more than I would expect, and longer than it takes to retrieve the geometry.

By exploiting QueryExtentAsync it has reduced my total processing time from 9 hours to 3 hours, so thank you for that.

I am using the Shapefile that can be found at http://www.environment.gov.au/fed/catalog/search/resource/downloadData.page?uuid=%7B4448CACD-9DA8-43.... It is the ArcView Shapefile with terrestrial in the name. They also publish a GeoDatabase, but I have no experience with these. Would they be quicker?

Just to explain my application. I run programs for Radio Amateurs (HAMs) where they can operate from either a park, or within 1km of a silo. There are 3000 parks, and they are many polygons in shape. They can also operate from within 1km of a silo, which is just a point. Being a greedy lot, they wish to know where they can operate from both at once. To find the intersection of all parks with all silos, is the typical N squared problem, so I have had to optimise the search strategy a bit. The current algorithm is:

for each park (3000 of them)
  get park extent (QueryExtentAsync)
  add a buffer of 1km to park extent
  SQL fetch all silos within that extent
  for each candidate silo (usually 2-10)
    Get park geometry for park if don't have it (QueryFeaturesAsync) already
    Test for overlap with park (unbuffered) and silo with 1km buffer applied
  next
next

Your tip about QueryExtentAsync has made a significant difference to the performance, however, iterating through a FeatureQueryResult still remains excruciatingly slow. Returning the geometry only takes 1-2 sec, so it's hard to understand why iterating this collection to detect overlap takes so long.

0 Kudos
MarcHillman
New Contributor III

Curious observation. For QueryExtentAsync to work, .ReturnGeometry must be true, which is the default. The subsequent QueryFeaturesAsync call is now much faster, presumably because the geometry is already cached (which is pretty clever of it).

Timings are now

QueryExtentAsync = 2.5s, (OK I guess)

QueryFeaturesAsync = ~0.5s (obviously some caching going on)

Iterate the resulting FeatureQueryResult = 5s

The use of a preceding QueryExtentAsync seems to have sped things up significantly, but iteration is still much slower than expected.

 

0 Kudos
MarcHillman
New Contributor III

I suspect the FeatureQueryResult object is seriously broken. Not only is iterating it very slow, but the simple reference to the .Any property of the object takes 3 seconds, even if empty.

0 Kudos
dotMorten_esri
Esri Frequent Contributor

If performance is critical, I wouldn't recommend using shapefiles. Instead I'd suggest you download the .gdb file from that source, open it in Pro and export that dataset to a runtime geodatabase, then use that instead.

https://pro.arcgis.com/en/pro-app/2.7/help/data/geodatabases/manage-mobile-gdb/mobile-geodatabases.h...

0 Kudos
MarcHillman
New Contributor III

Thank you for the suggestion. I am skeptical the performance issue is shapefile related for 2 reasons.

1. Under esriarcgisruntime 10.x there was no performance issue. Problem seems to be since 100.x
2. Querying seems to provide adequate performance. It is iterating the query result that is the issue. Even if the query result is no more than a series of pointers to the shapefile, the .Any property should not take 3 seconds, particularly when the result is empty - there is no shapefile access involved.

0 Kudos