Folks, it looks like DB2 (UDB 8.2.2/Linux) cache replacement policy is not "good" when multiple performing full table scans are involved.
Here's what I'm trying to do: I'm transforming columns into rows of a source table loanevt(loanno char(7),evtyp char(6),captl decimal(9,2),tax decimal(5,2),expns decimal(5,2),bonus decimal(5,2)) into a target table named events using the following query:
insert into events (loanno, evtyp, amtyp, amt)
select loanno, evtyp, 'CAPTL' as AMTYP, captl
from loanevt
where captl > 0
union all
select loanno, evtyp, 'TAX' as AMTYP, tax
from loanevt
where tax > 0
union all
select loanno, evtyp, 'EXPNS' as AMTYP, expns
from loanevt
where expns > 0
union all
select loanno, evtyp, 'BONUS' as AMTYP, bonus
from loanevt
where bonus > 0
The issue here is that this statement scans the loanevt table multiple times. However, I was expecting that as I increase the size of the buffer pool I would observe gradually lesser Phys. Reads. But this does not happen. Instead, the number of physical reads only drops (abruptly) when the input table can be totally fitted in the buffer pool.
I'm testing this with 5M records, so loanevt ends up with 26640 blocks (8K) read through TBSCAN.
With a buffer pool of 25600 blocks, I get this:
Buffer pool data logical reads = 110490
Buffer pool data physical reads = 104795
...
Total execution time (sec.ms) = 246.635994
With a buffer pool of 27000 blocks, I get this:
Buffer pool data logical reads = 110490
Buffer pool data physical reads = 26640
...
Total execution time (sec.ms) = 80.343795
It looks to me that DB2 is reading the scanned pages and marking them as MRU, this appears ok, I think this is how it should work. When it starts scanning the relation again to build up the result of the union, it will need the first block. Now, even if the buffer is one block smaller than the input relation, when the last block of loanevt is read-in, by age, block #1 is select as a victim. When block #1 of loanevt is read-in, then block #2 is the victim, when block #2 is read-in block #3 is the victim and on it goes.
I'm still making sense?
Anyway I could change this? I cannot afford a 1GB readpool to treat a real-world version of loanevt.
Any pointers would be greatly apreciated.
Thanks.