The Cache Clause

2
The Cache Clause Administration Tips Copyright © Howard Rogers 2001 10/17/2001 Page 1 of 2 How useful is the CACHE clause? About as useful as a hit on the head with a wet mackerel. It might have a limited use in Oracle 7. It's utterly redundant in Oracle 8.0 and above (though you can still set it if you are mad enough). The essential problem is full table scans. A full scan of a huge table would, left to its own devices, tend to flush everything out of the Buffer Cache. That would be a shame, since lots of little and extremely useful lookup tables would bite the dust, and there'd be a performance penalty to pay in getting the Buffer Cache re-populated with them afterwards. That's because, when determining which buffers to age out (i.e., flush) from the Buffer Cache, Oracle consults the Least Recently Used (LRU) list. Buffers at the Least Recently Used end of the LRU list will be aged out in preference to buffers at the Most Recently Used end of that list. So, if full table scans load their blocks onto the MRU end of the list, everything else gets shunted down further and further towards the LRU end. To avoid that problem, Oracle adopted the rule that blocks read by full table scans would not be considered the most recently used blocks at all (even though they were). Instead, they would be placed around half-way down the LRU list (onto what is sometimes called the 'cold half' of the list). That way, the MRU end of the LRU list (containing all the juicy buffers from our small lookup tables) would be protected to a degree from becoming swamped by blocks from a full scan. Then the trouble started: our small lookup tables are likely themselves (given that they are small) to first be read by a full table scan. Which means that they start life half-way down the LRU list, and are therefore at risk of being of aged out and flushed. But these full scans would be safe to load onto the MRU end of the list, because they are only small tables after all, and therefore aren't big enough to shunt too much down towards the LRU end of the list. So: how to distinguish between nasty, dangerous, performance-crippling full table scans which mustn't go near the MRU end of the LRU list, and the nice, small ones which ought to go to the MRU end of the LRU list?? Enter the CACHE clause. What it does is to over-ride Oracle's default full table scan behaviour. Blocks read during a full table scan from a table that has been created with (or altered to have) the CACHE clause will go to the MRU end of the LRU list. Sounds like a good idea. Why is it not useful?

description

So: how to distinguish between nasty, dangerous, performance-crippling full table scans which mustn't go near the MRU end of the LRU list, and the nice, small ones which ought to go to the MRU end of the LRU list?? It might have a limited use in Oracle 7. It's utterly redundant in Oracle 8.0 and above (though you can still set it if you are mad enough).

Transcript of The Cache Clause

The Cache Clause Administration Tips

Copyright © Howard Rogers 2001 10/17/2001 Page 1 of 2

How useful is the CACHE clause? About as useful as a hit on the head with a wet mackerel. It might have a limited use in Oracle 7. It's utterly redundant in Oracle 8.0 and above (though you can still set it if you are mad enough). The essential problem is full table scans. A full scan of a huge table would, left to its own devices, tend to flush everything out of the Buffer Cache. That would be a shame, since lots of little and extremely useful lookup tables would bite the dust, and there'd be a performance penalty to pay in getting the Buffer Cache re-populated with them afterwards. That's because, when determining which buffers to age out (i.e., flush) from the Buffer Cache, Oracle consults the Least Recently Used (LRU) list. Buffers at the Least Recently Used end of the LRU list will be aged out in preference to buffers at the Most Recently Used end of that list. So, if full table scans load their blocks onto the MRU end of the list, everything else gets shunted down further and further towards the LRU end. To avoid that problem, Oracle adopted the rule that blocks read by full table scans would not be considered the most recently used blocks at all (even though they were). Instead, they would be placed around half-way down the LRU list (onto what is sometimes called the 'cold half' of the list). That way, the MRU end of the LRU list (containing all the juicy buffers from our small lookup tables) would be protected to a degree from becoming swamped by blocks from a full scan. Then the trouble started: our small lookup tables are likely themselves (given that they are small) to first be read by a full table scan. Which means that they start life half-way down the LRU list, and are therefore at risk of being of aged out and flushed. But these full scans would be safe to load onto the MRU end of the list, because they are only small tables after all, and therefore aren't big enough to shunt too much down towards the LRU end of the list. So: how to distinguish between nasty, dangerous, performance-crippling full table scans which mustn't go near the MRU end of the LRU list, and the nice, small ones which ought to go to the MRU end of the LRU list?? Enter the CACHE clause. What it does is to over-ride Oracle's default full table scan behaviour. Blocks read during a full table scan from a table that has been created with (or altered to have) the CACHE clause will go to the MRU end of the LRU list. Sounds like a good idea. Why is it not useful?

The Cache Clause Administration Tips

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

For a start, it doesn't guarantee that those blocks will stay at the MRU end of the list. An absolutely enormous full table scan will tend to flush the entire LRU list (and hence the contents of the Buffer Cache) regardless. And second, the "problem" of blocks from small, frequently used tables (without the CACHE clause) being full-table scanned half-way down the LRU list is not as serious as it sounds... if the table is "frequently used", where are its blocks likely to migrate to in fairly short order? Er, that's right: the MRU end of the LRU list. Where they are first read to, and where they end up over time are two different things. So the CACHE clause was designed to fix up a problem that will tend to fix itself up over time anyway. What's more, there is a much better way (in Oracle 8.0 and above, at least) of trying to ensure that small, useful tables don't get shunted out of the Buffer Cache by large full table scans -and that's to use the KEEP and RECYCLE buffer pools feature (which I've described in my answer to the "How do I keep a table in memory" tip). In Oracle 7, the KEEP and RECYCLE buffer pools trick isn't available to you at all -so you may find some small performance gains to be had by using the CACHE clause when creating small, frequently used tables. But you're going to be hard-pressed to measure those performance gains, and quite frankly, I simply wouldn't bother.