Question

We currently maintain 'N' tablespaces per Oracle instance. We'd like to see if we can scale it up. Is there a way to find shared pool usage per tablespace ? Does Oracle maintain these statistics as well ?

Oracle gives us access to many views, so i'd like to know how best to approach this.

Was it helpful?

Solution

You're adding additional custom functionality to an application so using tablespaces as a proxy is not appropriate. The performance impact of your new functionality will depend on the workload that your new functionality generates which is independent of what tablespace(s) the object(s) the new code references happen to reside in. The tablespace that an object resides in does not affect performance.

Knowing how the buffer cache is being used at present doesn't give you much insight into how additional functionality, which would cause new blocks to be cached and would force some existing blocks to age out more quickly, would impact the performance of existing functionality. Unless you have a tiny toy application, the buffer cache will be full of something. The fact that the buffer cache is full, though, doesn't tell you whether, at the margin, the additional blocks that would be aged out in order to support the new functionality would cause millions of additional physical reads or whether they would have no impact on performance.

Beyond the buffer cache, though, the new functionality might impact performance by consuming additional CPU cycles, putting additional load on the I/O subsystem, or by locking rows that would negatively impact the performance of existing functionality. In theory, it's possible to do some ballpark estimates of how additional pieces of functionality are likely to impact an existing system. This is not, however, a task for the faint of heart, it's a pretty sophisticated endeavor.

Fortunately, since you're the one building the new functionality, you have a much easier solution. You can benchmark the existing application in your lower environments, add the new functionality, and then benchmark the existing functionality with the new functionality in place. That lets you do a much more level comparison-- you're comparing transaction times before and after the change, for example, rather than measuring something like CPU consumption and trying to model how that would impact transaction times. And it is typically much easier to implement-- all you need is some sort of load test that exercises the existing functionality in a way that is generally similar to how it is used in prod.

OTHER TIPS

Does this give you what you need?

SELECT a.tablespace_name, a.file_name, a.bytes allocated_bytes, b.free_bytes 
FROM dba_data_files a, 
  (SELECT file_id, SUM(bytes) free_bytes FROM dba_free_space b GROUP BY file_id) b 
WHERE a.file_id=b.file_id ORDER BY a.tablespace_name;

You can run this to get shared memory pool stats. not exactly what you want but might help you.

SET serveroutput on;

DECLARE
   object_mem       NUMBER;
   shared_sql       NUMBER;
   cursor_mem       NUMBER;
   mts_mem          NUMBER;
   used_pool_size   NUMBER;
   free_mem         NUMBER;
   pool_size        VARCHAR2 (512);                     -- Now from V$SGASTAT
BEGIN
   -- Stored objects (packages, views)
   SELECT SUM (sharable_mem)
     INTO object_mem
     FROM v$db_object_cache;

   -- Shared SQL -- need to have additional memory if dynamic SQL used
   SELECT SUM (sharable_mem)
     INTO shared_sql
     FROM v$sqlarea;

   -- User Cursor Usage -- run this during peak usage.
   --  assumes 250 bytes per open cursor, for each concurrent user.
   SELECT SUM (250 * users_opening)
     INTO cursor_mem
     FROM v$sqlarea;

   -- For a test system -- get usage for one user, multiply by # users
   -- select (250 * value) bytes_per_user
   -- from v$sesstat s, v$statname n
   -- where s.statistic# = n.statistic#
   -- and n.name = 'opened cursors current'
   -- and s.sid = 25;  -- where 25 is the sid of the process
   -- MTS memory needed to hold session information for shared server users
   -- This query computes a total for all currently logged on users (run
   --  multiply by # users.
   SELECT SUM (VALUE)
     INTO mts_mem
     FROM v$sesstat s, v$statname n
    WHERE s.statistic# = n.statistic# AND n.NAME = 'session uga memory max';

   -- Free (unused) memory in the SGA: gives an indication of how much memory
   -- is being wasted out of the total allocated.
   SELECT BYTES
     INTO free_mem
     FROM v$sgastat
    WHERE NAME = 'free memory' AND pool = 'shared pool';

   -- For non-MTS add up object, shared sql, cursors and 20% overhead.
   used_pool_size := ROUND (1.2 * (object_mem + shared_sql + cursor_mem));

   -- For MTS mts contribution needs to be included (comment out previous line)
   -- used_pool_size := round(1.2*(object_mem+shared_sql+cursor_mem+mts_mem));
   SELECT SUM (BYTES)
     INTO pool_size
     FROM v$sgastat
    WHERE pool = 'shared pool';

   -- Display results
   DBMS_OUTPUT.put_line ('Shared Pool Memory Utilization Report');
   DBMS_OUTPUT.put_line ('Obj mem:  ' || TO_CHAR (object_mem) || ' bytes');
   DBMS_OUTPUT.put_line ('Shared sql:  ' || TO_CHAR (shared_sql) || ' bytes');
   DBMS_OUTPUT.put_line ('Cursors:  ' || TO_CHAR (cursor_mem) || ' bytes');
   -- dbms_output.put_line ('MTS session: '||to_char (mts_mem) || ' bytes');
   DBMS_OUTPUT.put_line (   'Free memory: '
                         || TO_CHAR (free_mem)
                         || ' bytes '
                         || '('
                         || TO_CHAR (ROUND (free_mem / 1024 / 1024, 2))
                         || 'MB)'
                        );
   DBMS_OUTPUT.put_line (   'Shared pool utilization (total):  '
                         || TO_CHAR (used_pool_size)
                         || ' bytes '
                         || '('
                         || TO_CHAR (ROUND (used_pool_size / 1024 / 1024, 2))
                         || 'MB)'
                        );
   DBMS_OUTPUT.put_line (   'Shared pool allocation (actual):  '
                         || pool_size
                         || ' bytes '
                         || '('
                         || TO_CHAR (ROUND (pool_size / 1024 / 1024, 2))
                         || 'MB)'
                        );
   DBMS_OUTPUT.put_line (   'Percentage Utilized:  '
                         || TO_CHAR (ROUND (used_pool_size / pool_size * 100))
                        );
END;
/
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top