{"id":5054,"date":"2015-07-05T20:22:07","date_gmt":"2015-07-05T18:22:07","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/"},"modified":"2015-07-05T20:22:07","modified_gmt":"2015-07-05T18:22:07","slug":"resultcache-hint-expiration-options","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/","title":{"rendered":"RESULT_CACHE hint expiration options"},"content":{"rendered":"<h2>By Franck Pachot<\/h2>\n<p>.<br \/>\nThe result cache is very nice when base tables are static: get the result without any buffer get, without any join or sorts. But as soon as any DML occurs on one of the tables the result is based on, then result cache is invalidated. And cache misses are quite expensive. You can think of it as a materialized view in memory. But with materialized views, you can accept to see stale results in order to avoid frequent refreshes. Let&#8217;s see how we can control stale results with undocumented options.<\/p>\n<h3>Test case<\/h3>\n<p>I&#8217;m creating a basic table.<\/p>\n<pre><code>22:30:44 SQL&gt; create table DEMO as select rownum id from xmltable('1 to 100000');\nTable created.\n&nbsp;\n22:30:44 SQL&gt; exec if dbms_result_cache.flush then dbms_output.put_line('Flushed.'); end if;\nPL\/SQL procedure successfully completed.\n<\/code><\/pre>\n<h3>RESULT_CACHE<\/h3>\n<p>On that table, I&#8217;ll do a simple select with the RESULT_CACHE hint.<\/p>\n<pre><code>22:30:44 SQL&gt; set autotrace on\n22:30:44 SQL&gt; select \/*+ <b>result_cache<\/b> *\/ count(*) from DEMO;\n&nbsp;\n  COUNT(*)\n----------\n    100000\n&nbsp;\nExecution Plan\n----------------------------------------------------------\nPlan hash value: 2180342005\n&nbsp;\n------------------------------------------------------------------------------------------\n| Id  | Operation           | Name                       | Rows  | Cost (%CPU)| Time     |\n------------------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT    |                            |     1 |    46   (0)| 00:00:01 |\n|   1 |  RESULT CACHE       | 2x5f91pfn5p6882f6szxj50jwf |       |            |          |\n|   2 |   SORT AGGREGATE    |                            |     1 |            |          |\n|   3 |    TABLE ACCESS FULL| DEMO                       |   100K|    46   (0)| 00:00:01 |\n------------------------------------------------------------------------------------------\n&nbsp;\nResult Cache Information (identified by operation id):\n------------------------------------------------------\n&nbsp;\n   1 - column-count=1; dependencies=(DEMO.DEMO); attributes=(single-row); name=\"select \/*+ result_cache *\/ count(*) from DEMO\"\n&nbsp;\nStatistics\n----------------------------------------------------------\n          5  recursive calls\n          0  db block gets\n        159  consistent gets\n        153  physical reads\n          0  redo size\n        358  bytes sent via SQL*Net to client\n        499  bytes received via SQL*Net from client\n          2  SQL*Net roundtrips to\/from client\n          0  sorts (memory)\n          0  sorts (disk)\n          1  rows processed\n<\/code><\/pre>\n<p>We have read the 150 blocks of the DEMO table. The result cache has been loaded. Here are the objects and dependency:<\/p>\n<pre><code>22:30:44 SQL&gt; set autotrace off\n22:30:44 SQL&gt; select * from v$result_cache_dependency;\n&nbsp;\n RESULT_ID  DEPEND_ID  OBJECT_NO     CON_ID\n---------- ---------- ---------- ----------\n         1          0     112463          0\n&nbsp;\n22:30:44 SQL&gt; select id,type,status,name,cache_id,invalidations from v$result_cache_objects order by id;\n&nbsp;\n ID TYPE       STATUS    NAME                           CACHE_ID                     INV\n--- ---------- --------- ------------------------------ --------------------------- ----\n  0 Dependency Published DEMO.DEMO                      DEMO.DEMO                      0\n  1 Result     Published select \/*+ result_cache *\/ cou 2x5f91pfn5p6882f6szxj50jwf     0<\/code><\/pre>\n<p>We can read it as: the query result (id=1) depends on the table (id=0).<\/p>\n<p>If I run it another time:<\/p>\n<pre><code>22:30:45 SQL&gt; select \/*+ result_cache *\/ count(*) from DEMO;\n&nbsp;\n  COUNT(*)\n----------\n    100000\n&nbsp;\nExecution Plan\n----------------------------------------------------------\nPlan hash value: 2180342005\n&nbsp;\n------------------------------------------------------------------------------------------\n| Id  | Operation           | Name                       | Rows  | Cost (%CPU)| Time     |\n------------------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT    |                            |     1 |    46   (0)| 00:00:01 |\n|   1 |  RESULT CACHE       | 2x5f91pfn5p6882f6szxj50jwf |       |            |          |\n|   2 |   SORT AGGREGATE    |                            |     1 |            |          |\n|   3 |    TABLE ACCESS FULL| DEMO                       |   100K|    46   (0)| 00:00:01 |\n------------------------------------------------------------------------------------------\n&nbsp;\nResult Cache Information (identified by operation id):\n------------------------------------------------------\n&nbsp;\n   1 - column-count=1; dependencies=(DEMO.DEMO); attributes=(single-row); name=\"select \/*+ result_cache *\/ count(*) from DEMO\"\n&nbsp;\nStatistics\n----------------------------------------------------------\n          0  recursive calls\n          0  db block gets\n          0  consistent gets\n          0  physical reads\n          0  redo size\n        358  bytes sent via SQL*Net to client\n        499  bytes received via SQL*Net from client\n          2  SQL*Net roundtrips to\/from client\n          0  sorts (memory)\n          0  sorts (disk)\n          1  rows processed<\/code><\/pre>\n<p>No block get at all. The result was in cache.<\/p>\n<h3>dependencies<\/h3>\n<p>If we do any kind of DML on the tables the result cache depends on:<\/p>\n<pre><code>22:30:45 SQL&gt; delete from DEMO where null is not null;\n0 rows deleted.\n&nbsp;\n22:30:45 SQL&gt; commit;\nCommit complete.<\/code><\/pre>\n<p>Then the cache is invalidated:<\/p>\n<pre><code>22:30:45 SQL&gt; select * from v$result_cache_dependency;\nno rows selected\n&nbsp;\n22:30:45 SQL&gt; select id,type,status,name,cache_id,invalidations from v$result_cache_objects order by id;\n&nbsp;\n ID TYPE       STATUS    NAME                           CACHE_ID                     INV\n--- ---------- --------- ------------------------------ --------------------------- ----\n  0 Dependency Published DEMO.DEMO                      DEMO.DEMO                      1\n  1 Result     Invalid   select \/*+ result_cache *\/ cou 2x5f91pfn5p6882f6szxj50jwf     0<\/code><\/pre>\n<p>and another run will have to load the cache again:<\/p>\n<pre><code>22:30:45 SQL&gt; set autotrace on\n22:30:45 SQL&gt; select \/*+ result_cache *\/ count(*) from DEMO;\n&nbsp;\n  COUNT(*)\n----------\n    100000\n&nbsp;\nExecution Plan\n----------------------------------------------------------\nPlan hash value: 2180342005\n&nbsp;\n------------------------------------------------------------------------------------------\n| Id  | Operation           | Name                       | Rows  | Cost (%CPU)| Time     |\n------------------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT    |                            |     1 |    46   (0)| 00:00:01 |\n|   1 |  RESULT CACHE       | 2x5f91pfn5p6882f6szxj50jwf |       |            |          |\n|   2 |   SORT AGGREGATE    |                            |     1 |            |          |\n|   3 |    TABLE ACCESS FULL| DEMO                       |   100K|    46   (0)| 00:00:01 |\n------------------------------------------------------------------------------------------\n&nbsp;\nResult Cache Information (identified by operation id):\n------------------------------------------------------\n&nbsp;\n   1 - column-count=1; dependencies=(DEMO.DEMO); attributes=(single-row); name=\"select \/*+ result_cache *\/ count(*) from DEMO\"\n&nbsp;\nStatistics\n----------------------------------------------------------\n          0  recursive calls\n          0  db block gets\n        157  consistent gets\n          0  physical reads\n          0  redo size\n        358  bytes sent via SQL*Net to client\n        499  bytes received via SQL*Net from client\n          2  SQL*Net roundtrips to\/from client\n          0  sorts (memory)\n          0  sorts (disk)\n          1  rows processed\n&nbsp;\n22:30:46 SQL&gt; set autotrace off\n22:30:46 SQL&gt; select * from v$result_cache_dependency;\n&nbsp;\n RESULT_ID  DEPEND_ID  OBJECT_NO     CON_ID\n---------- ---------- ---------- ----------\n         2          0     112463          0\n&nbsp;\n22:30:46 SQL&gt; select id,type,status,name,cache_id,invalidations from v$result_cache_objects order by id;\n&nbsp;\n ID TYPE       STATUS    NAME                           CACHE_ID                     INV\n--- ---------- --------- ------------------------------ --------------------------- ----\n  0 Dependency Published DEMO.DEMO                      DEMO.DEMO                      1\n  1 Result     Invalid   select \/*+ result_cache *\/ cou 2x5f91pfn5p6882f6szxj50jwf     0\n  2 Result     Published select \/*+ result_cache *\/ cou 2x5f91pfn5p6882f6szxj50jwf     0<\/code><\/pre>\n<p>This is the only documented behaviour: the cache is invalidated if and only if there has been some DML on the tables it depends on.<\/p>\n<h3>RESULT_CACHE(SHELFLIFE=seconds)<\/h3>\n<p>I flush the cache and run the same with the undocumented result cache hint option: SHELFLIFE=10 seconds:<\/p>\n<pre><code>22:30:46 SQL&gt; exec if dbms_result_cache.flush then dbms_output.put_line('Flushed.'); end if;\nPL\/SQL procedure successfully completed.\n&nbsp;\n22:30:46 SQL&gt; set autotrace on\n22:30:46 SQL&gt; select \/*+ result_cache(shelflife=10) *\/ count(*) from DEMO;\n&nbsp;\n  COUNT(*)\n----------\n    100000\n&nbsp;\nExecution Plan\n----------------------------------------------------------\nPlan hash value: 2180342005\n&nbsp;\n------------------------------------------------------------------------------------------\n| Id  | Operation           | Name                       | Rows  | Cost (%CPU)| Time     |\n------------------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT    |                            |     1 |    46   (0)| 00:00:01 |\n|   1 |  RESULT CACHE       | 2x5f91pfn5p6882f6szxj50jwf |       |            |          |\n|   2 |   SORT AGGREGATE    |                            |     1 |            |          |\n|   3 |    TABLE ACCESS FULL| DEMO                       |   100K|    46   (0)| 00:00:01 |\n------------------------------------------------------------------------------------------\n&nbsp;\nResult Cache Information (identified by operation id):\n------------------------------------------------------\n&nbsp;\n   1 - column-count=1; dependencies=(DEMO.DEMO); attributes=(single-row, shelflife=10); name=\"select \/*+ result_cache(shelflife=10) *\/ count(*) from DEMO\"<\/code><\/pre>\n<p>we see the &#8216;shelflife&#8217; attribute but the dependency is the same as without the option:<\/p>\n<pre><code>22:30:46 SQL&gt; set autotrace off\n22:30:46 SQL&gt; select * from v$result_cache_dependency;\n&nbsp;\n RESULT_ID  DEPEND_ID  OBJECT_NO     CON_ID\n---------- ---------- ---------- ----------\n         1          0     112463          0\n&nbsp;\n22:30:46 SQL&gt; select id,type,status,name,cache_id,invalidations from v$result_cache_objects order by id;\n&nbsp;\n ID TYPE       STATUS    NAME                           CACHE_ID                     INV\n--- ---------- --------- ------------------------------ --------------------------- ----\n  0 Dependency Published DEMO.DEMO                      DEMO.DEMO                      0\n  1 Result     Published select \/*+ result_cache(shelfl 2x5f91pfn5p6882f6szxj50jwf     0<\/code><\/pre>\n<p>I run the query again 5 seconds later:<\/p>\n<pre><code>22:30:51 SQL&gt; set autotrace on\n22:30:51 SQL&gt; select \/*+ result_cache(shelflife=10) *\/ count(*) from DEMO;\n&nbsp;\n  COUNT(*)\n----------\n    100000\n&nbsp;\nExecution Plan\n----------------------------------------------------------\nPlan hash value: 2180342005\n&nbsp;\n------------------------------------------------------------------------------------------\n| Id  | Operation           | Name                       | Rows  | Cost (%CPU)| Time     |\n------------------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT    |                            |     1 |    46   (0)| 00:00:01 |\n|   1 |  RESULT CACHE       | 2x5f91pfn5p6882f6szxj50jwf |       |            |          |\n|   2 |   SORT AGGREGATE    |                            |     1 |            |          |\n|   3 |    TABLE ACCESS FULL| DEMO                       |   100K|    46   (0)| 00:00:01 |\n------------------------------------------------------------------------------------------\n&nbsp;\nResult Cache Information (identified by operation id):\n------------------------------------------------------\n&nbsp;\n   1 - column-count=1; dependencies=(DEMO.DEMO); attributes=(single-row, shelflife=10); name=\"select \/*+ result_cache(shelflife=10) *\/ count(*) from DEMO\"\n&nbsp;\nStatistics\n----------------------------------------------------------\n          0  recursive calls\n          0  db block gets\n          0  consistent gets\n          0  physical reads\n          0  redo size\n        358  bytes sent via SQL*Net to client\n        499  bytes received via SQL*Net from client\n          2  SQL*Net roundtrips to\/from client\n          0  sorts (memory)\n          0  sorts (disk)\n          1  rows processed\n&nbsp;\n22:30:51 SQL&gt; set autotrace off\n22:30:51 SQL&gt; select * from v$result_cache_dependency;\n&nbsp;\n RESULT_ID  DEPEND_ID  OBJECT_NO     CON_ID\n---------- ---------- ---------- ----------\n         1          0     112463          0\n&nbsp;\n22:30:51 SQL&gt; select id,type,status,name,cache_id,invalidations from v$result_cache_objects order by id;\n&nbsp;\n ID TYPE       STATUS    NAME                           CACHE_ID                     INV\n--- ---------- --------- ------------------------------ --------------------------- ----\n  0 Dependency Published DEMO.DEMO                      DEMO.DEMO                      0\n  1 Result     Published select \/*+ result_cache(shelfl 2x5f91pfn5p6882f6szxj50jwf     0<\/code><\/pre>\n<p>Nothing special here. No DML occured so the result is still valid (&#8216;published&#8217;)<\/p>\n<h3>expiration<\/h3>\n<p>But let&#8217;s wait 5 more seconds and run it again:<\/p>\n<pre><code>22:30:56 SQL&gt; select * from v$result_cache_dependency;\n&nbsp;\n RESULT_ID  DEPEND_ID  OBJECT_NO     CON_ID\n---------- ---------- ---------- ----------\n         1          0     112463          0\n&nbsp;\n22:30:56 SQL&gt; select id,type,status,name,cache_id,invalidations from v$result_cache_objects order by id;\n&nbsp;\n ID TYPE       STATUS    NAME                           CACHE_ID                     INV\n--- ---------- --------- ------------------------------ --------------------------- ----\n  0 Dependency Published DEMO.DEMO                      DEMO.DEMO                      0\n  1 Result     Expired   select \/*+ result_cache(shelfl 2x5f91pfn5p6882f6szxj50jwf     0<\/code><\/pre>\n<p>The status has changed, it&#8217;s now EXPIRED because the 10 seconds shelflife has passed on since the cache was loaded.<\/p>\n<pre><code>22:30:56 SQL&gt;\n22:30:56 SQL&gt; set autotrace on\n22:30:56 SQL&gt; select \/*+ result_cache(shelflife=10) *\/ count(*) from DEMO;\n&nbsp;\n  COUNT(*)\n----------\n    100000\n&nbsp;\nExecution Plan\n----------------------------------------------------------\nPlan hash value: 2180342005\n&nbsp;\n------------------------------------------------------------------------------------------\n| Id  | Operation           | Name                       | Rows  | Cost (%CPU)| Time     |\n------------------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT    |                            |     1 |    46   (0)| 00:00:01 |\n|   1 |  RESULT CACHE       | 2x5f91pfn5p6882f6szxj50jwf |       |            |          |\n|   2 |   SORT AGGREGATE    |                            |     1 |            |          |\n|   3 |    TABLE ACCESS FULL| DEMO                       |   100K|    46   (0)| 00:00:01 |\n------------------------------------------------------------------------------------------\n&nbsp;\nResult Cache Information (identified by operation id):\n------------------------------------------------------\n&nbsp;\n   1 - column-count=1; dependencies=(DEMO.DEMO); attributes=(single-row, shelflife=10); name=\"select \/*+ result_cache(shelflife=10) *\/ count(*) from DEMO\"\n&nbsp;\nStatistics\n----------------------------------------------------------\n          0  recursive calls\n          0  db block gets\n        157  consistent gets\n          0  physical reads\n          0  redo size\n        358  bytes sent via SQL*Net to client\n        499  bytes received via SQL*Net from client\n          2  SQL*Net roundtrips to\/from client\n          0  sorts (memory)\n          0  sorts (disk)\n          1  rows processed<\/code><\/pre>\n<p>here I have a cache miss even if no DML occured on the tables it depends on.<\/p>\n<pre><code>22:30:56 SQL&gt; select * from v$result_cache_dependency;\n&nbsp;\n RESULT_ID  DEPEND_ID  OBJECT_NO     CON_ID\n---------- ---------- ---------- ----------\n         2          0     112463          0\n&nbsp;\n22:30:56 SQL&gt; select id,type,status,name,cache_id,invalidations from v$result_cache_objects order by id;\n&nbsp;\n ID TYPE       STATUS    NAME                           CACHE_ID                     INV\n--- ---------- --------- ------------------------------ --------------------------- ----\n  0 Dependency Published DEMO.DEMO                      DEMO.DEMO                      0\n  1 Result     Invalid   select \/*+ result_cache(shelfl 2x5f91pfn5p6882f6szxj50jwf     0\n  2 Result     Published select \/*+ result_cache(shelfl 2x5f91pfn5p6882f6szxj50jwf     0<\/code><\/pre>\n<p>When I run a query using an expired result cache, that cache becomes invalid, the query is fully run (150 block gets) and new result cache populated.<\/p>\n<p>Note that in addition to the shelflife expiration, the dependency on DML is still invalidating the result cache:<\/p>\n<pre><code>22:30:56 SQL&gt; delete from DEMO where null is not null;\n0 rows deleted.\n&nbsp;\n22:30:56 SQL&gt; commit;\nCommit complete.\n&nbsp;\n22:30:56 SQL&gt; select * from v$result_cache_dependency;\nno rows selected\n&nbsp;\n22:30:56 SQL&gt; select id,type,status,name,cache_id,invalidations from v$result_cache_objects order by id;\n&nbsp;\n ID TYPE       STATUS    NAME                           CACHE_ID                     INV\n--- ---------- --------- ------------------------------ --------------------------- ----\n  0 Dependency Published DEMO.DEMO                      DEMO.DEMO                      1\n  1 Result     Invalid   select \/*+ result_cache(shelfl 2x5f91pfn5p6882f6szxj50jwf     0\n  2 Result     Invalid   select \/*+ result_cache(shelfl 2x5f91pfn5p6882f6szxj50jwf     0<\/code><\/pre>\n<p>So with SHELFLIFE we have two reasons for invalidations: dependency and expiration.<\/p>\n<h3>RESULT_CACHE(SNAPSHOT=seconds)<\/h3>\n<p>There is another undocumented option for the result cache hint: SNAPSHOT which also taked a number of seconds. Let&#8217;s try it:<\/p>\n<pre><code>22:30:56 SQL&gt; exec if dbms_result_cache.flush then dbms_output.put_line('Flushed.'); end if;\nPL\/SQL procedure successfully completed.\n&nbsp;\n22:30:56 SQL&gt; set autotrace on\n22:30:56 SQL&gt; select \/*+ result_cache(snapshot=10) *\/ count(*) from DEMO;\n&nbsp;\n  COUNT(*)\n----------\n    100000\n&nbsp;\nExecution Plan\n----------------------------------------------------------\nPlan hash value: 2180342005\n&nbsp;\n------------------------------------------------------------------------------------------\n| Id  | Operation           | Name                       | Rows  | Cost (%CPU)| Time     |\n------------------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT    |                            |     1 |    46   (0)| 00:00:01 |\n|   1 |  RESULT CACHE       | 2x5f91pfn5p6882f6szxj50jwf |       |            |          |\n|   2 |   SORT AGGREGATE    |                            |     1 |            |          |\n|   3 |    TABLE ACCESS FULL| DEMO                       |   100K|    46   (0)| 00:00:01 |\n------------------------------------------------------------------------------------------\n&nbsp;\nResult Cache Information (identified by operation id):\n------------------------------------------------------\n&nbsp;\n   1 - column-count=1; attributes=(single-row, snapshot=10); name=\"select \/*+ result_cache(snapshot=10) *\/ count(*) from DEMO\"\n&nbsp;\nStatistics\n----------------------------------------------------------\n          1  recursive calls\n          0  db block gets\n        157  consistent gets\n          0  physical reads\n          0  redo size\n        358  bytes sent via SQL*Net to client\n        499  bytes received via SQL*Net from client\n          2  SQL*Net roundtrips to\/from client\n          0  sorts (memory)\n          0  sorts (disk)\n          1  rows processed\n&nbsp;\n22:30:56 SQL&gt; set autotrace off\n22:30:56 SQL&gt; select * from v$result_cache_dependency;\nno rows selected\n&nbsp;\n22:30:56 SQL&gt; select id,type,status,name,cache_id,invalidations from v$result_cache_objects order by id;\n&nbsp;\n ID TYPE       STATUS    NAME                           CACHE_ID                     INV\n--- ---------- --------- ------------------------------ --------------------------- ----\n  0 Result     Published select \/*+ result_cache(snapsh 2x5f91pfn5p6882f6szxj50jwf     0<\/code><\/pre>\n<p>The cache has been populated here, but there is no dependency. Let&#8217;s try DML on base table:<\/p>\n<pre><code>22:30:56 SQL&gt; delete from DEMO where null is not null;\n0 rows deleted.\n&nbsp;\n22:30:56 SQL&gt; commit;\nCommit complete.\n&nbsp;\n22:30:56 SQL&gt; select * from v$result_cache_dependency;\nno rows selected\n&nbsp;\n22:30:56 SQL&gt; select id,type,status,name,cache_id,invalidations from v$result_cache_objects order by id;\n&nbsp;\n ID TYPE       STATUS    NAME                           CACHE_ID                     INV\n--- ---------- --------- ------------------------------ --------------------------- ----\n  0 Result     Published select \/*+ result_cache(snapsh 2x5f91pfn5p6882f6szxj50jwf     0<\/code><\/pre>\n<p>A SNAPSHOT result cache is not invalidated by DML on base tables.<\/p>\n<p>But if we wait 10 seconds:<\/p>\n<pre><code>22:31:06 SQL&gt; select id,type,status,name,cache_id,invalidations from v$result_cache_objects order by id;\n&nbsp;\n ID TYPE       STATUS    NAME                           CACHE_ID                     INV\n--- ---------- --------- ------------------------------ --------------------------- ----\n  0 Result     Expired   select \/*+ result_cache(snapsh 2x5f91pfn5p6882f6szxj50jwf     0<\/code><\/pre>\n<p>The status is expired, as with the shelflife. Next execution will invalidate it.<\/p>\n<h3>Conclusion<\/h3>\n<p>There are two reasons to invalidate a result cache: DML on dependency, or expiration after a number of seconds. And we can use any combination of them with undocumented hints. Oracle itself uses them internally. SNAPSHOT is used by Active Dynamic Sampling: stale result are acceptable for one hour. SHELFLIFE is used on dictionary views bases on X$ tables where dependency cannot be tracked.<\/p>\n<p>I hope it will get documented in future releases. There are some cases where we can accept stale results in order to get better performance. We already do that with materialized views, so why not do it with result cache?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>By Franck Pachot . The result cache is very nice when base tables are static: get the result without any buffer get, without any join or sorts. But as soon as any DML occurs on one of the tables the result is based on, then result cache is invalidated. And cache misses are quite expensive. [&hellip;]<\/p>\n","protected":false},"author":27,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[198,59],"tags":[96,522],"type_dbi":[],"class_list":["post-5054","post","type-post","status-publish","format-standard","hentry","category-database-management","category-oracle","tag-oracle","tag-undocumented"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>RESULT_CACHE hint expiration options - dbi Blog<\/title>\n<meta name=\"description\" content=\"Oracle Enterprise Edition result cache: invalidation on dependency (documented) and shelflife (undocumented)\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"RESULT_CACHE hint expiration options\" \/>\n<meta property=\"og:description\" content=\"Oracle Enterprise Edition result cache: invalidation on dependency (documented) and shelflife (undocumented)\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2015-07-05T18:22:07+00:00\" \/>\n<meta name=\"author\" content=\"Oracle Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Oracle Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/\"},\"author\":{\"name\":\"Oracle Team\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\"},\"headline\":\"RESULT_CACHE hint expiration options\",\"datePublished\":\"2015-07-05T18:22:07+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/\"},\"wordCount\":569,\"commentCount\":0,\"keywords\":[\"Oracle\",\"undocumented\"],\"articleSection\":[\"Database management\",\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/\",\"name\":\"RESULT_CACHE hint expiration options - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"datePublished\":\"2015-07-05T18:22:07+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\"},\"description\":\"Oracle Enterprise Edition result cache: invalidation on dependency (documented) and shelflife (undocumented)\",\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"RESULT_CACHE hint expiration options\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\",\"name\":\"Oracle Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"caption\":\"Oracle Team\"},\"url\":\"https:\/\/www.dbi-services.com\/blog\/author\/oracle-team\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"RESULT_CACHE hint expiration options - dbi Blog","description":"Oracle Enterprise Edition result cache: invalidation on dependency (documented) and shelflife (undocumented)","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/","og_locale":"en_US","og_type":"article","og_title":"RESULT_CACHE hint expiration options","og_description":"Oracle Enterprise Edition result cache: invalidation on dependency (documented) and shelflife (undocumented)","og_url":"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/","og_site_name":"dbi Blog","article_published_time":"2015-07-05T18:22:07+00:00","author":"Oracle Team","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Oracle Team","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/"},"author":{"name":"Oracle Team","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee"},"headline":"RESULT_CACHE hint expiration options","datePublished":"2015-07-05T18:22:07+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/"},"wordCount":569,"commentCount":0,"keywords":["Oracle","undocumented"],"articleSection":["Database management","Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/","url":"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/","name":"RESULT_CACHE hint expiration options - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2015-07-05T18:22:07+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee"},"description":"Oracle Enterprise Edition result cache: invalidation on dependency (documented) and shelflife (undocumented)","breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/resultcache-hint-expiration-options\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"RESULT_CACHE hint expiration options"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee","name":"Oracle Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","caption":"Oracle Team"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/oracle-team\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/5054","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=5054"}],"version-history":[{"count":0,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/5054\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=5054"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=5054"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=5054"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=5054"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}