Managing the SGA
Based on ML Notes:
                          100709.1 Top Parameters Affecting Performance
                        1006591.6 How to Determine the SGA Size (8.0, 8i, 9i)
                            61340.1 Calculating the Size of the Shared Pool
                            46053.1 Windows NT Memory Architecture Overview:
                          107866.1 Analyst's Survival Guide for Oracle on Windows NT
                            46001.1 Oracle and the Windows NT memory architecture
                          118883.1 Diagnosing Memory Problems with Oracle on NT
 

Showing size of the SGA
SGA size information are displayed upon startup of the database. It can also be displayed using svrmgrl or sqlplus.  See examples below.

8.1.X
 - svrmgrl or sqlplus /nolog
   connect internal
   show sga

 9.X
 - sqlplus
SQL> show sga

 Different sub-divisions of the SGA
Sample from svrmgrl SHOW SGA:

 Total System Global Area   23460696 bytes
 Fixed Size                    72536 bytes
 Variable Size              22900736 bytes
 Database Buffers             409600 bytes
 Redo Buffers                  77824 bytes

 * Total System Global Area
 - Total in bytes of all the sub-divisions that makes up the SGA.

 * Fixed Size
 - Contains general information about the state of the database and the instance, which the background processes need to access.
 - No user data is stored here.
 - This area is usually less than 100k in size.

* Variable Size
 - This section is influenced by the following init.ora parameters
     shared_pool_size
     large_pool_size
     java_pool_size
 - See 'Approximating Size of the SGA' section of this article for version specific information.

*  Database Buffers
 - Holds copies of data blocks read from datafiles.
  size = db_block_buffers * block size

*  Redo Buffers
 - A circular buffer in the SGA that holds information about changes made to the database.
 - Enforced mininum is set to 4 times the maximum database block size for the host operating system.
 

Approximating size of the SGA
8.1.X
To approximate size of the SGA (Shared Global Area), use the following formula:
(db_block_buffers * block size) +    (shared_pool_size + large_pool_size + java_pool_size + log_buffers) + 1MB

9.X
In Oracle9i, the SGA can be configured as in prior releases to be static, or can now be dynamically configured.
The size of the dynamic SGA is determined by the values of the following database initialization parameters: DB_BLOCK_SIZE, DB_CACHE_SIZE, SHARED_POOL_SIZE, and LOG_BUFFER.

Beginning with Oracle9i, the SGA infrastructure is dynamic. This means that the following primary parameters used to size the SGA can be changed while the instance is running:

- Buffer cache ( DB_CACHE_SIZE) -- the size in bytes of the cache of standard blocks
- Shared pool ( SHARED _POOL_SIZE) -- the size in bytes of the area devoted to shared SQL and PL/SQL statements
- Large pool (LARGE_POOL_SIZE) (default is 0 bytes) -- the size in bytes of the large pool used in shared server systems for session memory, parallel execution for message buffers, and by backup and restore processes for disk I/O buffers.

The LOG_BUFFER parameter is used when buffering redo entries to a redo log. It is a static parameter and represents a very small portion of the SGA and can be changed only by stopping and restarting the database to read the changed value for this parameter from the initialization parameter file (init.ora).

Note that even though you cannot change the MAX_SGA_SIZE parameter value dynamically, you do have the option of changing any of its three dependent primary parameters: DB_CACHE_SIZE, SHARED_POOL_SIZE, and LARGE_POOL_SIZE to make memory tuning adjustments on the fly.
(NOTE:  LARGE_POOL_SIZE cannot be dynamically changed in Oracle 9.0.1, it is anticipated to be made dynamic in the next release).

To help you specify an optimal cache value, you can use the dynamic DB_CACHE_ADVICE parameter with statistics gathering enabled to predict behavior with different cache sizes through the V$DB_CACHE_ADVICE performance view. Use the ALTER SYSTEM...SET clause... statement to enable this parameter.

Beginning with Oracle9i, there is a concept of creating tablespaces with multiple block sizes and specifying cache sizes corresponding with each block size. The SYSTEM tablespace uses a standard block size and additional tablespaces can use up to four non-standard block sizes.

The standard block size is specified by the DB_BLOCK_SIZE parameter. Its cache size is specified by the DB_CACHE_SIZE parameter. Non-standard block sizes are specified by the BLOCKSIZE clause of the CREATE TABLESPACE statement. The cache size for each corresponding non-standard block size is specified using the notation: DB_nK_CACHE_SIZE parameter, where the value n is 2, 4, 8, 16, or 32 Kbytes.

The standard block size, known as the default block size, is usually set to the same size in bytes as the operating system block size, or a multiple of this size. The DB_CACHE_SIZE parameter, known as the DEFAULT cache size, specifies the size of the cache of standard block size (default is 48M bytes). The system tablespace uses the standard block size and the DEFAULT cache size.

Either the standard block size or any of the non-standard block sizes and their associated cache sizes can be used for any of the other tablespaces. Ifyou intend to use multiple block sizes in your database storage design, you must specify at least the DB_CACHE_SIZE and one DB_nK_CACHE_SIZE parameter value. You must specify all sub-caches for all the other non-standard block sizes that you intend to use. This block size/cache sizing scheme lets you use up to four different non-standard block sizes for your tablespaces and lets you specify respective cache sizes for each corresponding block size.

Because the DB_BLOCK_SIZE parameter value can be changed only by re-creating the database, the value for this parameter must be chosen carefully and remain unchanged for the life of the database.

To approximate size of the SGA (Shared Global Area), use following formula:
  DB_CACHE_SIZE + DB_KEEP_CACHE_SIZE + DB_RECYCLE_CACHE_SIZE + DB_nk_CACHE_SIZE  + SHARED_POOL_SIZE + LARGE_POOL_SIZE + JAVA_POOL_SIZE + LOG_BUFFERS + 1MB

NOTE:  ADD IN EACH DB_nk_CACHE_SIZE.  THERE CAN BE UP TO 4 DB_nk_CACHE_SIZE (2, 4, 8, 16, 32k) DEFINED.  ONE OF THE BLOCK SIZES IS THE DEFAULT BLOCK SIZE AND ITS CACHE SIZE IS DEFINED BY DB_CACHE_SIZE.

For more information see Note:61623.1
 

Calculating the Size of the Shared Pool (Note 61340.1)
Shared pool is the amount of fixed, preallocated space in the SGA for use by multi-threaded server session PGA, shared SQL area, and other small, dynamically allocated SGA data structures.
While analyzing shared pool sizing, it is helpful to first increase the shared pool to a very large value, so that the dynamically allocated SGA structures may be allowed to expand to a desirable size.  Once this sizing exercise has been completed, the shared pool may be downsized to the appropriate value.

Formula
        Max Session Memory * No. of concurrent users
        + Total Shared SQL Area Usage
        + PLSQL Sharable Memory
        + Minimum 30% Free Space
        ----------------------------------------------
        = Minimum Allowable Shared Pool

Example
   Find the SID for an example user session:
            select sid from v$process p, v$session s where p.addr=s.paddr and s.username='OPS$JSMITH';
        SID
        ----------
                 29

   Get the maximum session memory for this session:
            select value from v$sesstat s, v$statname n where s.statistic# = n.statistic# and n.name = 'session uga memory max' and sid=29;
        VALUE
        ----------
            273877

   Get the total shared SQL area:
            select sum(sharable_mem) from v$sqlarea;
        SUM(SHARAB
        ----------
           8936625

   Get the PLSQL sharable memory area:
            select sum(sharable_mem) from v$db_object_cache;
        SUM(SHARAB
        ----------
           4823537

   Example shared pool calculation:
        274K shared memory * 400 users
        +    9M Shared SQL Area
        +    5M PLSQL Sharable Memory
        +   60M Free Space (30%)
        ---------------------------------
        =  184M Shared Pool

In this example, the recommended shared pool value is 184M.
 

Top Parameters Affecting Performance
The parameters listed below are what we consider to be the top init.ora parameters which per se, affect database tuning.
=====================
DB_BLOCK_BUFFERS
SHARED_POOL_SIZE
SORT_AREA_SIZE
DBWR_IO_SLAVES
ROLLBACK_SEGMENTS
SORT_AREA_RETAINED_SIZE
SHARED_POOL_RESERVE_SIZE
=====================

DB_BLOCK_BUFFERS
The value of this parameter is very important for storing data into memory as users are requesting information from the system. DB_Block_Buffers are the number of buffers in the SGA cache that will be available for user data to be stored in memory.  The size of the buffer cache, which is used to cache db blocks in the SGA, is specified by this parameter. Because the data is cached, this reduces the amount of physical I/O.
In turn, the setting of this parameter has a large effect on the buffer cache hit ratio, which you generally want to be over 90%.  The hit ratio can be dynamically determined based on the following query:

 select round(((1-(sum(decode(name,
        'physical reads', value,0))/
        (sum(decode(name, 'db block gets', value,0))+
        (sum(decode(name, 'consistent gets', value, 0))))))*100),2)
        || '%' "Buffer Cache Hit Ratio"
        from v$sysstat;

The result of this query would be similar to the following:
        Buffer Cache Hit Ratio:
 97.63%

The implications of the DB_Block_Buffers being set too low are that the least recently used data will be flushed from memory.
 

SHARED_POOL_SIZE
This is the memory that is allocated to Oracle for areas like the data dictionary, stored procedures, and statements.  Comprising a large part of the SGA, the Shared_Pool_Size is comprised of the dictionary cache and library cache, and just like DB_Block_Buffers above, should not be set too low or too high.
The Shared_Pool_Size can be monitored through the data dictionary cache and the library cache.  Both should be continuously monitored for an appropriate hit ratio.
The data dictionary component can be monitored via v$rowcache using the following select statement:

        select (1-(sum(getmisses)/sum(gets))) * 100 "Hit Ratio"
        from v$rowcache;

You should see output similar to the following:
        Hit Ratio
  95.40%

You should aim to have this value over 90%.  The exception is when the database is first started, the value will be somewhere around 85%.

The library cache consists of shared SQL and PL/SQL areas.  When SQL is executed, the statement has to be parsed (or taken apart for further clarification).  The library cache reduces the overhead of this by maintaining parsed SQL and PL/SQL in the library cache.  When there is a subsequent execution of this statement, there will not be the need to re-parse the statement.  Essentially, you are reducing the work of the database.
We have discussed having the Shared_Pool_Size set too low, but adverse effects may comes from setting the Shared_Pool_Size too high as well.  Having the shared pool set too large increase the probability of latch contention when the database needs to find a free peace of memory to load a new statement. You can query v$sgastat to show the available free memory. This will tell you memory is being wasted.  As an example, let's look at the following problem:
         select name, bytes/1024/1024 "Size in MB"
         from v$sgastat
         where name='free memory';

You should see output similar to the following:
          NAME  Size in MB
  Free memory 39.6002884

What this return would tell you is that there is 39M of free memory in the shared pool, which would mean that the shared pool is being under utilized. If the shared pool was 70M, over half of it would be under utilized.  This  memory could be allocated elsewhere.
 

SORT_AREA_SIZE
The SORT_AREA_SIZE is an oft-misunderstood init.ora parameter.  Many believe that this parameter is an amount allocated for the users as a whole in terms of sorting.  Not true, the SORT_AREA_SIZE is what Oracle allocates per user process for sorting data.  Unlike the two previous parameters, the SORT_AREA_SIZE is outside of the SGA.  If the sort_area_size is too small, the process has to then be sorted on disk in the user's temporary tablespace. Where does this lead back?  Physical disk IO.
The SQL statements that typically generate sort activity are order by and group by clauses.  Activities such as create index generate sort activity as well.

Because tuning in memory is always preferred over sorting to disk, continuously monitoring the SORT_AREA_SIZE is always a good idea.  Having to sort in the temporary tablespace means accessing temporary segments.  Accessing temporary segments artificially decreases the hit ratio, so should be avoided in OLTP applications. Having a large sort_area_size value will open the possibility that each user uses a large amount of memory in the system generating swapping which in turn decrease the performance as well.
 

DBWR_IO_SLAVES
Another oft-misunderstood init.ora parameter, DBWR_IO_SLAVES was introduced in Oracle 8.  This parameter was to replace DB_WRITERS that was available before Oracle 8.  The truth is that DB_WRITERS is still available in Oracle 8 under the name of DB_WRITER_PROCESSES as there are still a number of issues to work out with DBWR_IO_SLAVES.

DBWR_IO_SLAVES was introduced in Oracle 8 to allow for asynchronous I/O of slave writer processes, if it is available on the OS Platform.  As the name implies, there is a master process and slaves processes, which are defined by this parameter setting.
 

ROLLBACK_SEGMENTS
This parameter, available in all versions of Oracle, specifies the number of rollback segments that are explicitly brought online during instance startup. Rollback segments are areas of the database that record transactions should the transactions need to be rolled back or (in Windows terms, 'undo').  The rollback segments consists of contiguous or adjoined extents.  The extents are used in a circular (round-robin) order, and move from one extent to the next after the current extent is full.
Rollback segments are important to the database, as they are used to provide read consistency, undo of transactions, and recovery.

You can look at v$waitstat table in order to monitor contention between the rollback segments.  The following query would be useful in examining contention among the rollback segments:
 Select a. name, b.extents, b.rssize, b.xacts, b.waits,
        b. gets, optsize, status
 From v$rollname a, v$rollstat b
 Where a.usn = b.usn;

You should see results similar to the following:

NAME EXTENTS RSSIZE XACTS WAITS GETS OPTSIZE STATUS
SYSTEM 4 540672 1 0 51  ONLINE
RB1 2 10240000 0 0 427 10240000 ONLINE
RB2 2 10240000 1 0 425 10240000 ONLINE
RB3 2 10240000 1 0 422 10240000 ONLINE
RB4 2 10240000 0 0 421 10240000 ONLINE

If you run the above query, and the column "xacts" (which are active transactions) are continually above 1 for the RBS's, you will probably need to increase the number of rollback segments to avoid the possibility of contention.  If the waits are greater than zero, and this is normal processing, there may also be a need to increase the number of rollback segments.
 

SORT_AREA_RETAINED_SIZE
Another one of the init.ora parameters which affect sorting on the system, SORT_AREA_RETAINED_SIZE is the size that the SORT_AREA_SIZE is actually reduced to once the sort is complete.  This parameter should be set less than or equal to the parameter SORT_AREA_SIZE.
The SORT_AREA_RETAINED_SIZE complements the SORT_AREA_SIZE because memory is held for the entire duration of the sort, and it allows multiple sort areas of memory if there are more than one sort within the same sql  statement.  On the downside, this memory is released not when the statement is finished, but when the session is exited.  If you compare this to SORT_AREA_SIZE, the memory allocated to the SORT_AREA_SIZE gets released when the last row has been fetched from within the sort.
The SORT_AREA_RETAINED_SIZE is, as any memory parameter, limited by physical memory.  The recommended setting for both this parameter and SORT_AREA_SIZE is 65K-1MB.
 

SHARED_POOL_RESERVE_SIZE
Specifies the allocation of a certain amount of the shared pool for large objects.  In effects, you are reserving some portion of the shared pool.  The default setting of this parameter is 5% of your  shared_pool_size setting. This parameter is measured in bytes.
Setting this value to ensures that the majority of the area within the shared pool is not being used for large objects, but rather in a "separate area"