SlideShare une entreprise Scribd logo
1  sur  3
Télécharger pour lire hors ligne
Keeping a Table in Memory                                                       Administration Tips




How do I keep a table in memory?

The short answer is: you can't.

Packages and procedures can be kept in the Library Cache of the shared pool: execute
dbms_shared_pool.keep('name_of_package') will guarantee that the named package or
procedure will never age out of the Library Cache.

But table data is stored in the Buffer Cache, not the Library Cache, and there is no
equivalent to the 'keep' procedure to keep it there.

Nor, frankly, is there much need to. The Buffer Cache is managed by the "Least Recently
Used" list. Blocks which are frequently used (i.e., are useful to many Users) will be at the
Most Recently Used (MRU) end of the LRU list. Deeply unpopular blocks which are seldom
used will be at the Least Recently Used (LRU) end of the list. When Oracle has to choose
which blocks to age out of the Buffer Cache to make room for new arrivals, it chooses the
ones at the LRU end of the LRU list. So, if your table is worth keeping in memory, because
it is hugely important to your application and is therefore constantly accessed, it will tend
to stay in memory automatically, because its blocks will always be at the MRU end of the
LRU list. Forcing an unpopular table to be "kept" in the buffer cache would simply be a
waste of buffers.

That said, it is possible for a popular table to be 'washed out' of the Buffer Cache because
some looney decides to do a 'select * from enormous_table' -we need to find room for a
bazillion new blocks of data, there aren't enough free buffers, so we just flush the entire
LRU list (MRU end and all) to make as much room as we can. Bye-bye useful table blocks.

Can that be stopped? Sort of... but Oracle even has a mechanism for trying to avoid this
problem too. Usually, when Oracle reads a block of data off disk, it (naturally enough)
places it onto the MRU end of the LRU list (it's the most recently touched block, after all).
But any full table scans you do have the blocks they touch placed around half-way down
the LRU list. That's designed to prevent any 'select *' queries from flushing out the entire
LRU list, but can't guarantee that a particularly large full tablescan won't nevertheless be
forced to flush the entire list.

Introduced in Oracle 8.0, however, was the concept of dividing your Buffer Cache into
separate Buffer Pools. There are three possible: the DEFAULT pool (which behaves exactly
as an undivided Buffer Cache would), the RECYCLE pool (which is designed to flush blocks
out of the Cache as quickly as possible) and the KEEP pool (which is designed to allow
blocks to hang around in memory for as long as possible). You must always have a
DEFAULT pool, but whether you have both a RECYCLE and a KEEP is up to you: either or
both is acceptable.



Copyright © Howard Rogers 2001            10/17/2001                                     Page 1 of 3
Keeping a Table in Memory                                                        Administration Tips


The first thing to say about this, however, is that the KEEP pool provides no guarantees: if
a large full tablescan inadvertently goes through the KEEP pool, it will still flush the entire
pool of its more useful buffers.

To set up the multiple pools in Oracle 8.0 or Oracle 8.1, you configure a few init.ora
parameters (all aspects of Buffer Cache management have changed significantly in Oracle
9i).

DB_BLOCK_LRU_LATCHES sets up the total number of latches available to manage the
Buffer Cache (each pool needs its own set of latches)

DB_BLOCK_BUFFERS sets up the total number of buffers. Without further qualification,
they all belong to the DEFAULT pool.

BUFFER_POOL_KEEP sets up the number of buffers to be allocated to the KEEP pool,
taking those buffers out of the total previously set by DB_BLOCK_BUFFERS. It also
specifies how many of the total available latches should be used to manage this pool.

BUFFER_POOL_RECYCLE does the same for the RECYCLE pool. Again, the number of
buffers specified here comes from the total pool of buffers allocated by
DB_BLOCK_BUFFERS, and it also specifies a number of latches to manage the pool.

You might, for example, set up four init.ora lines like this:

DB_BLOCK_LRU_LATCHES=6
DB_BLOCK_BUFFERS=20000
BUFFER_POOL_KEEP=(BUFFERS:12000, LRU_LATCHES:3)
BUFFER_POOL_RECYCLE=(BUFFERS:2000, LRU_LATCHES:1)

...and that will mean there are 20,000 buffers in total, of which 12,000 are assigned to the
KEEP pool,managed by 3 latches; 2,000 are allocated to the RECYCLE pool, managed by a
single latch; and (by implication) 6,000 buffers are left for the DEFAULT pool, managed by
2 latches. (Note that the syntax changed between 8.0 and 8i -the above example works
for 8i only. In Oracle 8.0, you the syntax was simply "buffer_pool_keep=12000" and so on -
with no mention of the latches).

Note that a latch must manage at least 50 buffers, so you couldn't have a line reading, for
example: BUFFER_POOL_KEEP=(buffers:100, lru_latches 3) -because that would require at
least 150 buffers.

Having set up a number of different buffer pools, you have then to tell Oracle to which
pool blocks from a particular table should be sent. If you miss out this step, then a table's
blocks will always be sent to the DEFAULT pool by, er... default.

You can do this at table (or index) creation time. For example:

Copyright © Howard Rogers 2001             10/17/2001                                     Page 2 of 3
Keeping a Table in Memory                                                       Administration Tips




CREATE    TABLE ALBUM(
PHOTOID NUMBER,
PHOTODESC CHAR(15))
STORAGE (BUFFER_POOL             RECYCLE)
TABLESPACE DATA4;


Blocks from this table will now always be loaded into the RECYCLE pool (and if,
incidentally, you haven't actually defined such a pool, its blocks will be loaded into the
DEFAULT pool instead).

You can also change a table (or index) to use a particular pool after it's already been
created:

ALTER    TABLE MUSIC STORAGE          (BUFFER_POOL KEEP);
ALTER    INDEX MUSIC_PK          STORAGE (BUFFER_POOL KEEP);


What tables and indexes should be directed to the RECYCLE pool? Basically, large ones
that are subject to lots of random reads (the random reads is important: it means that the
blocks Frank reads are unlikely to be needed by Scott when he does some reads later). A
table which is around twice the size of the entire DEFAULT pool subject to random reads is
a prime candidate -using our parameters above, and assuming an 8K block size, that would
mean that any tables bigger than (2 x 6000 x 8)K would be a good candidate (by my
calculations, that's around 96M).

How about the KEEP pool? What tables and indexes should go in there? Relatively small
tables that are frequently accessed in their entirety are good candidates here. The
standard advice is that a frquently-used table which is smaller than around 10% of the
DEFAULT pool is a prime candidate (again, using our earlier init.ora parameters, that
would suggest tables smaller than around 5M would be KEEP material).

By setting up multiple pools in the Buffer Cache in this way, and then making sure big
tables are directed to the RECYCLE pool whilst small ones go to the KEEP pool, you help
minimise the chances of a huge tablescan flushing out a small, useful table from the cache
(since the scan will be flushing the RECYCLE pool like crazy, and not touching the stuff in
the KEEP pool at all). But you can never stop a huge table, accidentally assigned to the
KEEP pool, from flushing all the small tables out.

You might also check out the tip on "How useful is the CACHE clause?", since that is
frequently touted as a means of achieving the 'pinning' of tables in memory. It isn't any
such thing, of course.




Copyright © Howard Rogers 2001                    10/17/2001                             Page 3 of 3

Contenu connexe

Plus de oracle documents (20)

Windowsosauthent
WindowsosauthentWindowsosauthent
Windowsosauthent
 
Whatistnsnames
WhatistnsnamesWhatistnsnames
Whatistnsnames
 
Whatisadatabaselink
WhatisadatabaselinkWhatisadatabaselink
Whatisadatabaselink
 
Varraysandnestedtables
VarraysandnestedtablesVarraysandnestedtables
Varraysandnestedtables
 
Userpasswrd
UserpasswrdUserpasswrd
Userpasswrd
 
Userlimit
UserlimitUserlimit
Userlimit
 
Undo internalspresentation
Undo internalspresentationUndo internalspresentation
Undo internalspresentation
 
Undo internals paper
Undo internals paperUndo internals paper
Undo internals paper
 
Tablespacelmt
TablespacelmtTablespacelmt
Tablespacelmt
 
Tablerename
TablerenameTablerename
Tablerename
 
Sql scripting sorcerypresentation
Sql scripting sorcerypresentationSql scripting sorcerypresentation
Sql scripting sorcerypresentation
 
Sql for dbaspresentation
Sql for dbaspresentationSql for dbaspresentation
Sql for dbaspresentation
 
Sequencereset
SequenceresetSequencereset
Sequencereset
 
Rollbacksizes
RollbacksizesRollbacksizes
Rollbacksizes
 
Rollbackshrinks
RollbackshrinksRollbackshrinks
Rollbackshrinks
 
Rollbacklmt
RollbacklmtRollbacklmt
Rollbacklmt
 
Rollbackblocking
RollbackblockingRollbackblocking
Rollbackblocking
 
Rollback1555s
Rollback1555sRollback1555s
Rollback1555s
 
Redosize
RedosizeRedosize
Redosize
 
Real liferecoverypresentation
Real liferecoverypresentationReal liferecoverypresentation
Real liferecoverypresentation
 

Keep

  • 1. Keeping a Table in Memory Administration Tips How do I keep a table in memory? The short answer is: you can't. Packages and procedures can be kept in the Library Cache of the shared pool: execute dbms_shared_pool.keep('name_of_package') will guarantee that the named package or procedure will never age out of the Library Cache. But table data is stored in the Buffer Cache, not the Library Cache, and there is no equivalent to the 'keep' procedure to keep it there. Nor, frankly, is there much need to. The Buffer Cache is managed by the "Least Recently Used" list. Blocks which are frequently used (i.e., are useful to many Users) will be at the Most Recently Used (MRU) end of the LRU list. Deeply unpopular blocks which are seldom used will be at the Least Recently Used (LRU) end of the list. When Oracle has to choose which blocks to age out of the Buffer Cache to make room for new arrivals, it chooses the ones at the LRU end of the LRU list. So, if your table is worth keeping in memory, because it is hugely important to your application and is therefore constantly accessed, it will tend to stay in memory automatically, because its blocks will always be at the MRU end of the LRU list. Forcing an unpopular table to be "kept" in the buffer cache would simply be a waste of buffers. That said, it is possible for a popular table to be 'washed out' of the Buffer Cache because some looney decides to do a 'select * from enormous_table' -we need to find room for a bazillion new blocks of data, there aren't enough free buffers, so we just flush the entire LRU list (MRU end and all) to make as much room as we can. Bye-bye useful table blocks. Can that be stopped? Sort of... but Oracle even has a mechanism for trying to avoid this problem too. Usually, when Oracle reads a block of data off disk, it (naturally enough) places it onto the MRU end of the LRU list (it's the most recently touched block, after all). But any full table scans you do have the blocks they touch placed around half-way down the LRU list. That's designed to prevent any 'select *' queries from flushing out the entire LRU list, but can't guarantee that a particularly large full tablescan won't nevertheless be forced to flush the entire list. Introduced in Oracle 8.0, however, was the concept of dividing your Buffer Cache into separate Buffer Pools. There are three possible: the DEFAULT pool (which behaves exactly as an undivided Buffer Cache would), the RECYCLE pool (which is designed to flush blocks out of the Cache as quickly as possible) and the KEEP pool (which is designed to allow blocks to hang around in memory for as long as possible). You must always have a DEFAULT pool, but whether you have both a RECYCLE and a KEEP is up to you: either or both is acceptable. Copyright © Howard Rogers 2001 10/17/2001 Page 1 of 3
  • 2. Keeping a Table in Memory Administration Tips The first thing to say about this, however, is that the KEEP pool provides no guarantees: if a large full tablescan inadvertently goes through the KEEP pool, it will still flush the entire pool of its more useful buffers. To set up the multiple pools in Oracle 8.0 or Oracle 8.1, you configure a few init.ora parameters (all aspects of Buffer Cache management have changed significantly in Oracle 9i). DB_BLOCK_LRU_LATCHES sets up the total number of latches available to manage the Buffer Cache (each pool needs its own set of latches) DB_BLOCK_BUFFERS sets up the total number of buffers. Without further qualification, they all belong to the DEFAULT pool. BUFFER_POOL_KEEP sets up the number of buffers to be allocated to the KEEP pool, taking those buffers out of the total previously set by DB_BLOCK_BUFFERS. It also specifies how many of the total available latches should be used to manage this pool. BUFFER_POOL_RECYCLE does the same for the RECYCLE pool. Again, the number of buffers specified here comes from the total pool of buffers allocated by DB_BLOCK_BUFFERS, and it also specifies a number of latches to manage the pool. You might, for example, set up four init.ora lines like this: DB_BLOCK_LRU_LATCHES=6 DB_BLOCK_BUFFERS=20000 BUFFER_POOL_KEEP=(BUFFERS:12000, LRU_LATCHES:3) BUFFER_POOL_RECYCLE=(BUFFERS:2000, LRU_LATCHES:1) ...and that will mean there are 20,000 buffers in total, of which 12,000 are assigned to the KEEP pool,managed by 3 latches; 2,000 are allocated to the RECYCLE pool, managed by a single latch; and (by implication) 6,000 buffers are left for the DEFAULT pool, managed by 2 latches. (Note that the syntax changed between 8.0 and 8i -the above example works for 8i only. In Oracle 8.0, you the syntax was simply "buffer_pool_keep=12000" and so on - with no mention of the latches). Note that a latch must manage at least 50 buffers, so you couldn't have a line reading, for example: BUFFER_POOL_KEEP=(buffers:100, lru_latches 3) -because that would require at least 150 buffers. Having set up a number of different buffer pools, you have then to tell Oracle to which pool blocks from a particular table should be sent. If you miss out this step, then a table's blocks will always be sent to the DEFAULT pool by, er... default. You can do this at table (or index) creation time. For example: Copyright © Howard Rogers 2001 10/17/2001 Page 2 of 3
  • 3. Keeping a Table in Memory Administration Tips CREATE TABLE ALBUM( PHOTOID NUMBER, PHOTODESC CHAR(15)) STORAGE (BUFFER_POOL RECYCLE) TABLESPACE DATA4; Blocks from this table will now always be loaded into the RECYCLE pool (and if, incidentally, you haven't actually defined such a pool, its blocks will be loaded into the DEFAULT pool instead). You can also change a table (or index) to use a particular pool after it's already been created: ALTER TABLE MUSIC STORAGE (BUFFER_POOL KEEP); ALTER INDEX MUSIC_PK STORAGE (BUFFER_POOL KEEP); What tables and indexes should be directed to the RECYCLE pool? Basically, large ones that are subject to lots of random reads (the random reads is important: it means that the blocks Frank reads are unlikely to be needed by Scott when he does some reads later). A table which is around twice the size of the entire DEFAULT pool subject to random reads is a prime candidate -using our parameters above, and assuming an 8K block size, that would mean that any tables bigger than (2 x 6000 x 8)K would be a good candidate (by my calculations, that's around 96M). How about the KEEP pool? What tables and indexes should go in there? Relatively small tables that are frequently accessed in their entirety are good candidates here. The standard advice is that a frquently-used table which is smaller than around 10% of the DEFAULT pool is a prime candidate (again, using our earlier init.ora parameters, that would suggest tables smaller than around 5M would be KEEP material). By setting up multiple pools in the Buffer Cache in this way, and then making sure big tables are directed to the RECYCLE pool whilst small ones go to the KEEP pool, you help minimise the chances of a huge tablescan flushing out a small, useful table from the cache (since the scan will be flushing the RECYCLE pool like crazy, and not touching the stuff in the KEEP pool at all). But you can never stop a huge table, accidentally assigned to the KEEP pool, from flushing all the small tables out. You might also check out the tip on "How useful is the CACHE clause?", since that is frequently touted as a means of achieving the 'pinning' of tables in memory. It isn't any such thing, of course. Copyright © Howard Rogers 2001 10/17/2001 Page 3 of 3