Yes, a block dump would give the complete and exact answer about a block content, txs for the confirmation.
I was thinking more in the line of means - let's say, a very big table suffered deletion in a so singular pattern that the data blocks are not completely free, a few rows yet exists in each datablock (and thus this blocks do not appears in DBMS_SPACE reports), this table will be archived (ie, no more data will be entered) and we want/need to release this space to re-use elsewhere this space.
My line of thinking was, for each "suspect" table :
- calculate (by hand) the ** mean ** row length rigth now, OR (with some clever manipulation finding blocks for each row of data) find the exact number of rows in each block
- find the total block size
- find the expected number of lines to be contained in a block (creating a "copy" of the suspect table structure and doing a lot of inserts only)
- check in the real suspect table if the mean number of lines present right now per block is very less than the expected number (analyzing the table and looking at the xx_TABLES columns) : if so, this table is a real candidate for any kind of shrink/move/rebuild, the space to be gained after that probably is significative.
It makes some sense ?
[]s
J. Laurindo Chiappa
OBS : in another point , I don't know if the % of data block occupation (given in DBMS_SPACE.FREE_SPACE via FS1/FS2/FS3/FS4, as
https://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:231414051079 ) could be used to find segments with a lot of semi-occupied data blocks and thus to-shrink candidates if we know that no more data will be entered....
February 29, 2016 - 11:55 pm UTC
Check out DBMS_ROWID if you want to drill into that.
eg
SQL> create table t1 as select * from dba_objects;
Table created.
SQL>
SQL> delete from t1
2 where object_id between 40000 and 50000
3 or mod(object_id,5) = 0;
27350 rows deleted.
SQL>
SQL> commit;
Commit complete.
SQL>
SQL> select rows_per_block, count(*)
2 from (
3 select
4 dbms_rowid.ROWID_RELATIVE_FNO(rowid) f,
5 dbms_rowid.ROWID_BLOCK_NUMBER(rowid) b,
6 count(*) rows_per_block
7 from t1
8 group by
9 dbms_rowid.ROWID_RELATIVE_FNO(rowid),
10 dbms_rowid.ROWID_BLOCK_NUMBER(rowid)
11 )
12 group by rows_per_block
13 order by 1;
ROWS_PER_BLOCK COUNT(*)
-------------- ----------
16 1
30 1
38 1
41 1
42 4
43 2
44 18
45 163
46 389
47 291
48 146
49 85
50 80
51 87
52 81
53 47
54 23
55 14
56 4
57 4
58 7
59 1
61 1
23 rows selected.