Friday, December 6, 2013

Library cache hit ratio

When configuring a brand new instance, it is impossible to know the correct size to make the shared pool cache. Typically, a DBA makes a first estimate for the cache size, then runs a representative workload on the instance, and examines the relevant statistics to see whether the cache is under-configured or over-configured.
For most OLTP applications, shared pool size is an important factor in application performance. Shared pool size is less important for applications that issue a very limited number of discrete SQL statements, such as decision support systems (DSS).
If the shared pool is too small, then extra resources are used to manage the limited amount of available space. This consumes CPU and latching resources, and causes contention. Optimally, the shared pool should be just large enough to cache frequently accessed objects. Having a significant amount of free memory in the shared pool is a waste of memory. When examining the statistics after the database has been running, a DBA should check that none of these mistakes are in the workload.

Shared Pool: Library Cache Statistics

When sizing the shared pool, the goal is to ensure that SQL statements that will be executed multiple times are cached in the library cache, without allocating too much memory.
The statistic that shows the amount of reloading (that is, reparsing) of a previously cached SQL statement that was aged out of the cache is the RELOADS column in the V$LIBRARYCACHE view. In an application that reuses SQL effectively, on a system with an optimal shared pool size, the RELOADS statistic will have a value near zero.

The INVALIDATIONS column in V$LIBRARYCACHE view shows the number of times library cache data was invalidated and had to be reparsed. INVALIDATIONS should be near zero. This means SQL statements that could have been shared were invalidated by some operation (for example, a DDL). This statistic should be near zero on OLTP systems during peak loads.

Another key statistic is the amount of free memory in the shared pool at peak times. The amount of free memory can be queried from V$SGASTAT, looking at the free memory for the shared pool. Optimally, free memory should be as low as possible, without causing any reloads on the system.

Lastly, a broad indicator of library cache health is the library cache hit ratio. This value should be considered along with the other statistics discussed in this section and other data, such as the rate of hard parsing and whether there is any shared pool or library cache latch contention.
These statistics are discussed in more detail in the following section.

V$LIBRARYCACHE

You can monitor statistics reflecting library cache activity by examining the dynamic performance view V$LIBRARYCACHE. These statistics reflect all library cache activity since the most recent instance startup.
Each row in this view contains statistics for one type of item kept in the library cache. The item described by each row is identified by the value of the NAMESPACE column. Rows with the following NAMESPACE values reflect library cache activity for SQL statements and PL/SQL blocks:
  • SQL AREA
  • TABLE/PROCEDURE
  • BODY
  • TRIGGER
Rows with other NAMESPACE values reflect library cache activity for object definitions that Oracle uses for dependency maintenance.

To examine each namespace individually, use the following query:
SELECT NAMESPACE, PINS, PINHITS, RELOADS, INVALIDATIONS
  FROM V$LIBRARYCACHE
 ORDER BY NAMESPACE;
NAMESPACE             PINS    PINHITS    RELOADS INVALIDATIONS
--------------- ---------- ---------- ---------- -------------
BODY                  8870       8819          0             0
CLUSTER                393        380          0             0
INDEX                   29          0          0             0
OBJECT                   0          0          0             0
PIPE                 55265      55263          0             0
SQL AREA          21536413   21520516      11204             2
TABLE/PROCEDURE   10775684   10774401          0             0
TRIGGER               1852       1844          0             0

To calculate the library cache hit ratio, use the following formula:
Library Cache Hit Ratio = sum(pinhits) / sum(pins)
SUM(PINHITS)/SUM(PINS)
----------------------
            .999466248
Note:
These queries return data from instance startup, rather than statistics gathered during an interval; interval statistics can better pinpoint the problem.

Examining the returned data leads to the following observations:
  • For the SQL AREA namespace, there were 21,536,413 executions.
  • 11,204 of the executions resulted in a library cache miss, requiring Oracle to implicitly reparse a statement or block or reload an object definition because it aged out of the library cache (that is, a RELOAD).
  • SQL statements were invalidated two times, again causing library cache misses.
  • The hit percentage is about 99.94%. This means that only .06% of executions resulted in reparsing.
The amount of free memory in the shared pool is reported in V$SGASTAT. Report the current value from this view using the following query:
SELECT * FROM V$SGASTAT 
 WHERE NAME = 'free memory'
   AND POOL = 'shared pool';

The output will be similar to the following:

POOL        NAME                            BYTES
----------- -------------------------- ----------
shared pool free memory                   4928280

If free memory is always available in the shared pool, then increasing the size of the pool offers little or no benefit. However, just because the shared pool is full does not necessarily mean there is a problem. It may be indicative of a well-configured system.
The following query uses the V$LIBRARYCACHE view to examine the reload ratio in the library cache:

0229_001
This next query uses the V$LIBRARYCACHE view to examine the library cache’s hit ratio in detail:

0229_002

Using Individual Library Cache Parameters to Diagnose Shared Pool Use

Using a modified query on the same table, you can see how each individual parameter makes up the library cache. This may help diagnose a problem or reveal overuse of the shared pool.

0229_003

0230_001

















Use the following list to help interpret the contents of the V$LIBRARYCACHE view:
  • namespace The object type stored in the library cache. The values SQL AREA, TABLE/PROCEDURE, BODY, and TRIGGER show the key types.
  • gets Shows the number of times an item in library cache was requested.
  • gethits Shows the number of times a requested item was already in the library cache.
  • gethitratio Shows the ratio of gethits to gets.
  • pins Shows the number of times an item in the library cache was executed.
  • pinhits Shows the number of times an item was executed when that item was already in the library cache.
  • pinhitratio Shows the ratio of pinhits to pins.
  • reloads Shows the number of times an item had to be reloaded into the library cache because it aged out or was invalidated.
Here is a script for measuring the library cache hit ratio:
SELECT 'Buffer Cache' NAME, ROUND ( (congets.VALUE + dbgets.VALUE - physreads.VALUE) * 100 / (congets.VALUE + dbgets.VALUE), 2 ) VALUE FROM v$sysstat congets, v$sysstat dbgets, v$sysstat physreads WHERE congets.NAME = 'consistent gets' AND dbgets.NAME = 'db block gets' AND physreads.NAME = 'physical reads' UNION ALL SELECT 'Execute/NoParse', DECODE (SIGN (ROUND ( (ec.VALUE - pc.VALUE) * 100 / DECODE (ec.VALUE, 0, 1, ec.VALUE), 2 ) ), -1, 0, ROUND ( (ec.VALUE - pc.VALUE) * 100 / DECODE (ec.VALUE, 0, 1, ec.VALUE), 2 ) ) FROM v$sysstat ec, v$sysstat pc WHERE ec.NAME = 'execute count' AND pc.NAME IN ('parse count', 'parse count (total)') UNION ALL SELECT 'Memory Sort', ROUND ( ms.VALUE / DECODE ((ds.VALUE + ms.VALUE), 0, 1, (ds.VALUE + ms.VALUE)) * 100, 2 ) FROM v$sysstat ds, v$sysstat ms WHERE ms.NAME = 'sorts (memory)' AND ds.NAME = 'sorts (disk)' UNION ALL SELECT 'SQL Area get hitrate', ROUND (gethitratio * 100, 2) FROM v$librarycache WHERE namespace = 'SQL AREA' UNION ALL SELECT 'Avg Latch Hit (No Miss)', ROUND ((SUM (gets) - SUM (misses)) * 100 / SUM (gets), 2) FROM v$latch UNION ALL SELECT 'Avg Latch Hit (No Sleep)', ROUND ((SUM (gets) - SUM (sleeps)) * 100 / SUM (gets), 2) FROM v$latch;

1 comment: