By Franck Pachot
.
12c is coming with more dynamic sampling, now called dynamic statistics and using the new Adaptive Dynamic Sampling algorithm. The goal is to have better estimations and better estimations gives better execution plans. However, this new approach will increase parse time because dynamic sampling kicks in more often, reads more blocs, and run more queries.
It’s probably not a problem for applications that are well designed, using bind variables to avoid to many parses, having good statistics (histograms where it makes sense, extended statistics for correlated columns). The SQL Plan Directives are there to trigger dynamic sampling only where misestimates have been observed. An OLTP application should not parse often, and should not have huge misestimates. A reporting use-case can spend more time on parsing and the few seconds spend to do dynamic sampling will probably benefit to the execution time.
In addition to that, in order to lower the dynamic sampling overhead, Oracle 12c Adaptive Dynamic Sampling run its queries with the /*+ result_cache(snapshot=3600) */ hint. The result is cached in the result cache and is not invalidated by dependencies. So even when the underlying table is updated, the dynamic sampling result is still valid in cache for 3600 seconds. This is why doing more dynamic sampling is not a big overhead according that:
- your result cache is sized accordingly. The default (0.25% of MEMORY_TARGET or 0.5% of SGA_TARGET or 1% of SHARED_POOL_SIZE) is probably too low to fit all the dynamic sampling result for frequently parsed statements.
- your result cache is enabled, meaning that you are in Enterprise Edition
So the question of the day is that I want to know if the RESULT_CACHE hint is just ignored in Standard Edition, or if there is a mechanism that allows it from Adaptive Dynamic Sampling.
If you have a bad application (not using bind variables, parse at each execution) and you are in Standard Edition, then there is a risk that the current parse contention you suffer from (CPU and latches) will be more problematic (more CPU and I/O). Let’s try the following:
declare
c sys_refcursor;
begin
for i in 1..100
loop
open c for 'select count(*) COUNT'||i||' from DEMO_TABLE where a+b=c+d';
dbms_sql.return_result(c);
null;
end loop;
end;
/
which run 100 times the same statement not using bind variables. So I’m parsing it each time, but it’s reading the same table with same predicate, so the result of dynamic sampling should not change a lot.
I’ll run it in Standard and Enterprise editions, with no dynamic sampling, and with the new AUTO level.
Enterprise Edition with Adaptive Dynamic Sampling
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
SQL> show parameter optimizer_dynamic_sampling
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
optimizer_dynamic_sampling integer 11
I’m in Enterprise Edition and with the new AUTO dynamic sampling level (11). Here are a few statistics from v$mystat:
NAME VALUE
------------------------------------------------------------ --------------------
parse count (hard) 204
parse count (total) 654
parse time cpu 59
parse time elapsed 79
recursive calls 4,460
session logical reads 312,198
when I check result cache statistics, I can see that ‘Find Count’ reaches the number of executions:
ID NAME VALUE
---------- ------------------------------ --------
1 Block Size (Bytes) 1024
2 Block Count Maximum 5120
3 Block Count Current 32
4 Result Size Maximum (Blocks) 256
5 Create Count Success 17
6 Create Count Failure 0
7 Find Count 104
8 Invalidation Count 0
9 Delete Count Invalid 0
10 Delete Count Valid 0
11 Hash Chain Length 1
12 Find Copy Count 104
13 Latch (Share) 0
Enterprise Edition without Dynamic Sampling
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
SQL> show parameter optimizer_dynamic_sampling
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
optimizer_dynamic_sampling integer 0
I’m in Enterprise Edition but disabled the dynamic sampling.
NAME VALUE
------------------------------------------------------------ --------------------
parse count (hard) 196
parse count (total) 342
parse time cpu 29
parse time elapsed 38
recursive calls 3,527
session logical reads 310,785
Here the parse time is smaller because we have less recursive calls. But the difference is not that big. Which means that the dynamic sampling was not a big overhead, thanks to result cache.
Standard Edition without Dynamic Sampling
Connected to:
Oracle Database 12c Release 12.1.0.1.0 - 64bit Production
SQL> show parameter optimizer_dynamic_sampling
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
optimizer_dynamic_sampling integer 0
I’m now connected to a Standard Edition with the dynamic sampling disabled:
NAME VALUE
------------------------------------------------------------ --------------------
parse count (hard) 167
parse count (total) 271
parse time cpu 26
parse time elapsed 22
recursive calls 2,131
session logical reads 309,449
This is very similar to the previous one. When dynamic sampling is not enabled, then the parsing time is similar in SE and in EE.
Standard Edition with Adaptive Dynamic Sampling
Connected to:
Oracle Database 12c Release 12.1.0.1.0 - 64bit Production
SQL> show parameter optimizer_dynamic_sampling
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
optimizer_dynamic_sampling integer 11
And finally here is the level=AUTO dynamic sampling in Standard Edition:
NAME VALUE
------------------------------------------------------------ --------------------
parse count (hard) 204
parse count (total) 649
parse time cpu 690
parse time elapsed 879
recursive calls 4,256
session logical reads 1,019,986
This is where we have a problem. Now wit Adaptive Dynamic Sampling, we are doing the same number of recursive calls as in EE but the result cache is not there to optimize them. My parse time is 10x higher. The number of blocks read is huge. there is no result cache here. And I’ve been running the queries from the same session where an internal cache is supposed to help.
Conclusion
The result cache – which is very important to ensure that the new 12c adaptive dynamic sampling is not a huge overhead at parsing – is not available in Standard Edition. Which means that if you already have parsing issues, you should solve them before gping to 12c or maybe you will have to disable the adaptive dynamic sampling.