Making Oracle queries faster: Cache query results using an SQL hint

2245
2
07-07-2022 08:18 AM
Bud
by
Honored Contributor

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:

  1. 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)
    1. 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.
  2. 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.
    1. 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.
    2. And to be clear, the Query Result Cache works perfectly fine for non-spatial queries, which I have lots of.
  3. 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.
    1. 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.
  4. 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.
    1. Note: Both ArcGIS Pro and ArcMap handle versioned edits properly — the XY Event Layer doesn't re-query until the edits are saved.
  5. 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.

2 Replies
Bud
by
Honored Contributor

@TanuHoque 

https://community.oracle.com/tech/apps-infra/discussion/comment/16848629/#Comment_16848629

"Good news! Spatial geometry ADTs are supported with the result cache mechanism, but you need to use the special optimizer hint: /*+ result_cache(force_spatial) */
For example:

SQL> SELECT /*+ result_cache(force_spatial) parallel(2) */ c.market.shape

2 FROM cola_markets_2 c

3 WHERE c.market.name = 'cola_a'

4 ORDER by c.mkt_id;"

0 Kudos
RonaldM
New Contributor

Hello Bud,

Just to let you know, Result Cache is at the time of writing an Oracle Enterprise Edition feature. 
It is a really handy "silver bullet", but comes with a licence caveat, and a memory caveat (depending on what you're doing).

https://docs.oracle.com/en/database/oracle/oracle-database/19/dblic/Licensing-Information.html

As a general guide, don't use hints in your SQL without chatting to your DBA first, hints are the exception, rather than the norm.
For sites or installations that aren't enterprise edition, you may be able to use subqueries, to get a similar effect in some cases.

I also noticed that you put a parallel(2) hint in one of your examples, again, don't do that unless you talk to your DBA first. Hits are the exeption, rather than the norm, and forced parallelism, also has some drawbacks relating to overhead of stitching the results of the parallel threads back together, using hash tables etc.

The hints that you're adding to your SQL are over-riding the optimiser: and 9 times out of 10, the Oracle Optimiser will Optimise, better than the hint, so again, treat them as the exception, rather than the norm.

Chat with your DBA, they'll steer you right.

Cheers - Ron.

0 Kudos