I came across a mechanism that can help with slow Oracle queries in some scenarios. I thought I'd share.
If we have a slow Oracle query, we can add the /*+ result_cache */ hint to the SQL. That hint tells Oracle to cache the result of the query until the next time the data is edited.
Query Result Cache in Oracle Database
I think that's a pretty powerful concept. Why re-compute a query every time we use it? Why not save the results until the underlying data changes?
--get st_geometry line startpoint
select /*+ result_cache */
objectid,
sde.st_x(sde.st_startpoint(shape)) as startpoint_x,
sde.st_y(sde.st_startpoint(shape)) as startpoint_y
from
sidewalks --initial load takes 20 seconds due to slow st_geometry functions (14,000 features)
I was quite happy when I figured that out!
With that said, there are significant limitations:
- A big problem is: The query can't output a geometry column (object column)...or rather, it can, but the result cache hint won't be invoked. In other words, the query can't be a traditional spatial query. That's a real bummer. (link1, link2, link3)
- With that said, we can still use geometry columns in the query, like I did in the above startpoint query. We just can't output a geometry column in the final result.
- But there is a workaround to #1 above...when the geometry type is points: Make an XY Event Layer in ArcGIS that converts the X & Y number columns to points in the map. I've found XY Event Layers to be surprisingly fast...so that solution seems to work well.
- But of course, that doesn't help us when we want the output to be lines, polygons, or multi-part points, since we can't create an Event Layer for those geometry types: Idea: Event layers for lines, polygons, and multi-part points (via WKT). I'm not aware of a workaround.
- And to be clear, the Query Result Cache works perfectly fine for non-spatial queries, which I have lots of.
- If the underlying data is edited often, then this might not be the right solution. For example, for my startpoint query above, it takes 20 seconds to re-cache the result, which feels like an eternity. If editing doesn't happen often, then it's not a problem...I can deal with the slow re-querying once and a while. But if editing happens regularly, then the entire query needs to be re-computed, even if only a single row was affected by edits.
- Whereas other solutions, such as populating a helper FC via attribute rules, database triggers, a materialized view, etc...only need to sync the edited rows, not the entire dataset. So those options might be better in some cases. Options for computing fields.
- For what it's worth, ArcGIS Pro seems to be a lot better at handling a cached XY Event Layer than ArcMap. ArcMap re-queries too often when making un-versioned edits...it re-queries after any mouse-click that modified a feature, even if unsaved, which is extremely aggravating. And when re-querying is happening in ArcMap, the mouse is captive to the loading icon...we can't do anything while we're waiting. Whereas ArcGIS Pro loads the layer in the background, allowing us to continue working while it loads. And in Pro, un-versioned edits won't trigger a re-query until the edits are saved, which is good.
- Note: Both ArcGIS Pro and ArcMap handle versioned edits properly — the XY Event Layer doesn't re-query until the edits are saved.
- There could be other limitations too. And I'm sure there are other database-related things to consider when storing results in the Oracle cache. Consult your DBA if in doubt, etc...
Summary:
As with any performance improvement mechanism, there are lots of tradeoffs...it's useful in some cases, but not others.
As mentioned, there are lots of alternative techniques we can use that have their own pros/cons. Maybe the benefit to this one is that it's dead-easy to implement (just add a line to your query), doesn't require begging the DBA team for stuff, and doesn't require custom code/additional FCs to manage.
I really like the idea of caching, rather than constantly re-computing for no reason.
I submitted a similar idea, but for caching in the application in ArcGIS: Event layers/query layers: Control caching settings for better performance.
Cheers.