ArcObjects – Troubleshooting and Improving ArcObjects Performance for Enterprise Geodatabase

arcgis-serverarcobjectscenterprise-geodatabase

We have developed a relatively complex geoprocessing routine using a C# / ArcObjects (COM) / ArcGIS Server 9.3.1 / ArcSDE 9.3.1 / Oracle 11g stack. Running the routine on a complete dataset takes many, many days and often does not complete.

Troubleshooting is hindered by the opaque nature of COM and the many levels of abstraction.

Specifics aside, could anyone suggest a heuristic for troubleshooting performance problems with ArcObjects? Hopefully the answer could be useful to others.

Edit: Using a profiler (JetBrains dotTrace), I can see that my problem calls are: ITable.GetRow, ITable.Select, ICursor.NextRow, ITable.Search, ISelectionSet.Search, ISelectionSet.get_IDs, IFeatureClass.Select, and IFeatureClass.GetFeature.

Best Answer

You should broaden your search to beyond ArcObjects as suggested in the comments to one of the other answers. Every single one of the methods you list are database access related.

  • Consider whether your data is properly indexed. Look at both attribute indexes as well as spatial index depending on your type of query.
  • Are you bringing back too many fields? If you only need a few fields, limit your query to those. Especially bringing back the geometry for feature classes is an expensive operation if you're not using it anywhere in your code.
  • Are you doing operations on the client (your ASP.NET app) that are better suited for the database? Do as much filtering as possible in your where-clause and/or spatial query to avoid transferring unneeded data across the wire from the database.
  • You're using queries on plain tables (ITable.Search, ITable.Select, etc.). It might make sense to use plain Oracle database access with ADO.NET instead of going through SDE via ArcObjects.
  • You're using selection sets, which may not be the most efficient way to do whatever you're trying to accomplish. Consider if transferring the data into memory and doing your filtering in plain .NET would be more efficient (even if it might use more memory in your web tier).