Why should I not re-organise my tables ?

Sometimes you can make things worse not better. Despite the clinical messing around listed in this article, if you scale up it shows that where you have large amounts of data, it’s not always best to assume you can improve things simply by re-organising.

Of course, there will be times when it does benefit.

Many clients ask us to do this first when they feel pressure on storage. Not always the best answer.

SQL> select segment_name, segment_type, extent_id, block_id, block_id+blocks-1 endblock from dba_extents where tablespace_name = ‘F’ order by block_id;
no rows selected

This is my seg.sql file. Where you see @seg, that’s the query running.

Ok, so we have no segments, and our user has no segments. We default to tablespace F, so all our queries can run on user_segments.

SQL> create table tst(id number, c varchar2(3999) default lpad(‘a’,3990,’a')) tablespace f;
Table created.
SQL> create index ind_one on tst(c) tablespace f;
Index created.
SQL> create index ind_two on tst(id) tablespace f;
Index created.

So, what did oracle create for us ?

SQL> select segment_name, segment_type, extent_id, block_id, block_id+blocks-1 endblock from dba_extents where tablespace_name = ‘F’ order by block_id;
no rows selected

This is because 11g does not create the segment until data has been added.

SQL> insert into tst(id) values (1);
1 row created.
SQL> @seg
SEGMENT_NAME                   SEGMENT_TYPE        EXTENT_ID   BLOCK_ID   ENDBLOCK
—————————— —————— ———- ———- ———-
TST                            TABLE                       0        128        135
IND_ONE                        INDEX                       0        136        143
IND_TWO                        INDEX                       0        144        151

Add a little data.

SQL> begin
2    for i in 1 .. 4 loop
3      insert into tst(id) values (i);
4    end loop;
5  end;
6  /
PL/SQL procedure successfully completed.
SQL> @seg
SEGMENT_NAME         SEGMENT_TYPE        EXTENT_ID   BLOCK_ID   ENDBLOCK
——————– —————— ———- ———- ———-
TST                  TABLE                       0        128        135
IND_TWO              INDEX                       0        136        143
IND_ONE              INDEX                       0        144        151
IND_ONE              INDEX                       1        152        159

Now we can see the ind_one, the first index has overflowed, and this occured before the table extended another extent. What if we roll back this transaction ?

SQL> rollback;
Rollback complete.
SQL> @seg
order by block_id;
SEGMENT_NAME         SEGMENT_TYPE        EXTENT_ID   BLOCK_ID   ENDBLOCK
——————– —————— ———- ———- ———-
TST                  TABLE                       0        128        135
IND_TWO              INDEX                       0        136        143
IND_ONE              INDEX                       0        144        151
IND_ONE              INDEX                       1        152        159

The storage, once allocated remains there.

SQL> create sequence dumseq start with 5;
Sequence created.

Repeatedly insert data until the next extent is allocated.

SQL> declare
2    cnt number;
3    ccnt number;
4  begin
5    select count(*) into cnt from user_extents;
6    ccnt:=cnt;
7    while (cnt = ccnt) loop
8      insert into tst(id) values (dumseq.nextval);
9      select count(*) into ccnt from user_extents;
10    end loop;
11  end;
12  /
PL/SQL procedure successfully completed.
SQL> @seg
SEGMENT_NAME         SEGMENT_TYPE        EXTENT_ID   BLOCK_ID   ENDBLOCK
——————– —————— ———- ———- ———-
TST                  TABLE                       0        128        135
IND_TWO              INDEX                       0        136        143
IND_ONE              INDEX                       0        144        151
IND_ONE              INDEX                       1        152        159
TST                  TABLE                       1        160        167

Table TST has extended. Let’s place something else in there, table tst2.

SQL> create table tst2 as select rownum id, lpad(‘a’,3990,’a') c from dual connect by level < 10000;
Table created.
SQL> @seg

I’ll break this down here to show only the pertinant rows. The start of the table remains the same.

SEGMENT_NAME         SEGMENT_TYPE        EXTENT_ID   BLOCK_ID     BLOCKS   ENDBLOCK
——————– —————— ———- ———- ———- ———-
TST                  TABLE                       0        128          8        135
IND_TWO              INDEX                       0        136          8        143
IND_ONE              INDEX                       0        144          8        151
IND_ONE              INDEX                       1        152          8        159
TST                  TABLE                       1        160          8        167
TST2                 TABLE                       0        168          8        175

There’s the start of the TST2 segments.

This increments from segment 0 to 15, at which point the blocks allocated change from 8 to 128.

TST2                 TABLE                      15        288          8        295
TST2                 TABLE                      16        384        128        511

At towards the end we see the size raise from 128K to 1M.

TST2                 TABLE                      78       8320        128       8447
TST2                 TABLE                      79       8448       1024       9471

So the segment size is growing.

Now, to clear the problem, let’s remove table tst from the datafile.

SQL> drop table tst purge;
Table dropped.

So our segments will start from block 168, as expected.

SQL> @seg
SEGMENT_NAME         SEGMENT_TYPE        EXTENT_ID   BLOCK_ID     BLOCKS   ENDBLOCK
——————– —————— ———- ———- ———- ———-
TST2                 TABLE                       0        168          8        175
TST2                 TABLE                       1        176          8        183

Now, we know TST went into the recyclebin, so we should check in there.

SQL> select * from user_recyclebin;
OBJECT_NAME                    ORIGINAL_NAME                    OPERATION TYPE                      TS_NAME
—————————— ——————————– ——— ————————- ——————————
CREATETIME          DROPTIME               DROPSCN PARTITION_NAME                   CAN CAN    RELATED BASE_OBJECT PURGE_OBJECT
——————- ——————- ———- ——————————– — — ———- ———– ————
SPACE
———-
BIN$Uv/Wu9DmRKelLSEsJfHKAA==$0 IND_ONE                          DROP      INDEX                     F
2011-04-01:12:28:04 2011-04-01:12:30:01   11046094                                  NO  YES      88364       88364        88365
16
BIN$OywpZjUISzyvhXfGTMFFZg==$0 IND_TWO                          DROP      INDEX                     F
2011-04-01:12:28:08 2011-04-01:12:30:01   11046098                                  NO  YES      88364       88364        88366
8
BIN$NX/1EyAbSwCLZPRwy5bSEA==$0 TST                              DROP      TABLE                     F
2011-04-01:12:27:59 2011-04-01:12:30:01   11046102                                  YES YES      88364       88364        88364
16
SQL> create table tst3(id number, c varchar2(3999) default lpad(‘a’,3990,’a')) tablespace f;
Table created.
SQL> create index ind_three on tst3(c) tablespace f;
Index created.
SQL> create index ind_four on tst3(id) tablespace f;
Index created.
SQL> insert into tst3(id) values (1);
1 row created.

Now check the segments query again and you will see tst3 going into the middle of the datafile. I’ve shortened the output again.

SEGMENT_NAME         SEGMENT_TYPE        EXTENT_ID   BLOCK_ID     BLOCKS   ENDBLOCK
——————– —————— ———- ———- ———- ———-
TST2                 TABLE                      15        288          8        295
TST3                 TABLE                       0        296          8        303
IND_THREE            INDEX                       0        304          8        311
IND_FOUR             INDEX                       0        312          8        319
TST2                 TABLE                      16        384        128        511

Why ? When the segment size of TST2 broke from 8 to 128, oracle had to find a multiple block of 128 in which to place the new segment. This leaves space from block 296 onwards as empty. Indeed you can see block 320 to 383 are not in use. We’d have to use this up to keep going. Let’s run our segment extend block again.

declare
cnt number;
ccnt number;
begin
select count(*) into cnt from user_extents;
ccnt:=cnt;
while (cnt = ccnt) loop
insert into tst3(id) values (dumseq.nextval);
select count(*) into ccnt from user_extents;
end loop;
end;
/

Keep running this until we use new blocks at the end of the listing.

SEGMENT_NAME         SEGMENT_TYPE        EXTENT_ID   BLOCK_ID     BLOCKS   ENDBLOCK
——————– —————— ———- ———- ———- ———-
TST2                 TABLE                      80       9472       1024      10495
IND_THREE            INDEX                       6      10496          8      10503
TST3                 TABLE                       4      10504          8      10511
IND_THREE            INDEX                       7      10512          8      10519
IND_THREE            INDEX                       8      10520          8      10527
96 rows selected.

Now we have reached the end of the allocated listing and started to use space at the end, still in 8k block sizes. Our end block is at 10527.

Time to ask a couple of questions.

Why did the first blocks not get re-used for table TST3 ?

What do you think re-organising the TST2 table will achieve now ?

Firstly, the blocks for table TST3 are still in use. The object has been dropped into the recyclebin, but the data remains on disk. Check the start of the output of our segments query.

SEGMENT_NAME         SEGMENT_TYPE        EXTENT_ID   BLOCK_ID     BLOCKS   ENDBLOCK
——————– —————— ———- ———- ———- ———-
TST2                 TABLE                       0        168          8        175
TST2                 TABLE                       1        176          8        183

Now flashback the table and check again.

SQL> flashback table tst to before drop;
Flashback complete.

And check the segments.

SQL> @seg
SEGMENT_NAME         SEGMENT_TYPE        EXTENT_ID   BLOCK_ID     BLOCKS   ENDBLOCK
——————– —————— ———- ———- ———- ———-
TST                  TABLE                       0        128          8        135
BIN$Uv/Wu9DmRKelLSEs INDEX                       0        136          8        143
JfHKAA==$0
BIN$OywpZjUISzyvhXfG INDEX                       0        144          8        151
TMFFZg==$0
BIN$Uv/Wu9DmRKelLSEs INDEX                       1        152          8        159
JfHKAA==$0
TST                  TABLE                       1        160          8        167
TST2                 TABLE                       0        168          8        175

Hmm, interesting. The segments are back in the original place and the indexs are there too. But they are called something else. These we have to rename.

SQL> alter index “BIN$Uv/Wu9DmRKelLSEsJfHKAA==$0″ rename to ind_one;
Index altered.
SQL> alter index “BIN$OywpZjUISzyvhXfGTMFFZg==$0″ rename to ind_two;
Index altered.
SQL> @seg
SEGMENT_NAME         SEGMENT_TYPE        EXTENT_ID   BLOCK_ID     BLOCKS   ENDBLOCK
——————– —————— ———- ———- ———- ———-
TST                  TABLE                       0        128          8        135
IND_ONE              INDEX                       0        136          8        143
IND_TWO              INDEX                       0        144          8        151
IND_ONE              INDEX                       1        152          8        159
TST                  TABLE                       1        160          8        167
TST2                 TABLE                       0        168          8        175

so, the space was not released and reused. Drop again using PURGE to clear the space as available on disk, and extend the tst3 table segments.

SQL> drop table tst purge;
Table dropped.

This is bearing in mind that the table tst3 will keep extending at 8k blocks until block 16.

SQL> @ext_tst3
PL/SQL procedure successfully completed.
SQL> @seg
SEGMENT_NAME         SEGMENT_TYPE        EXTENT_ID   BLOCK_ID     BLOCKS   ENDBLOCK
——————– —————— ———- ———- ———- ———-
IND_THREE            INDEX                       9        128          8        135
TST2                 TABLE                       0        168          8        175

And you can see segment IND_THREE has taken some of the space previously allocated to table TST. So, let’s see how fragmented this datafile really is.

What we need is a count of all blocks which are used or not. Let’s do it this way. Note the – 128 to remove the datafile header storage.

select maxblock-sblocks-128 from (select sum(blocks) sblocks from dba_extents where tablespace_name = ‘F’) a,
(select max(block_id+blocks) maxblock from dba_extents where tablespace_name = ‘F’) b;
MAXBLOCK-SBLOCKS-128
——————–
32

So, from the base of the file to the last occupied block, we have 32 free blocks not in use. That’s not bad. Let’s now try to re-organise the tablespace with the supposed aim of saving space.

Let’s move table TST2 first. This is the very large table by comparison.

SQL> alter table tst2 move tablespace f;
Table altered.
SQL> select maxblock-sblocks-128 from (select sum(blocks) sblocks from dba_extents where tablespace_name = ‘F’) a,
2  (select max(block_id+blocks) maxblock from dba_extents where tablespace_name = ‘F’) b;
MAXBLOCK-SBLOCKS-128
——————–
10360

Ouch. That’s made things much much worse in regard to free space in the datafile. Note that we cannot undo this move, be we can re-perform it again.

SQL> alter table tst2 move tablespace f;
Table altered.
SQL> select maxblock-sblocks-128 from (select sum(blocks) sblocks from dba_extents where tablespace_name = ‘F’) a,
2  (select max(block_id+blocks) maxblock from dba_extents where tablespace_name = ‘F’) b;
MAXBLOCK-SBLOCKS-128
——————–
32

Why did it do that ? It’s because of the distribution of the data in the datafile which mean that to rebuild the data, oracle had to go to the end of the datafile, write the table there, drop the original table and change the storage to point to the copied data. Because tst2 already occupied the space up to the highest extent, it created new extents to store the copied table in.

Here it is before the move. Where an object occupied contiguous blocks, I’ve just listed the first and last entries.

SQL> @seg
SEGMENT_NAME                   SEGMENT_TYPE        EXTENT_ID   BLOCK_ID     BLOCKS   ENDBLOCK
—————————— —————— ———- ———- ———- ———-
IND_THREE                      INDEX                       9        128          8        135
TST2                           TABLE                       0        168          8        175
……
TST2                           TABLE                      15        288          8        295
TST3                           TABLE                       0        296          8        303
IND_THREE                      INDEX                       0        304          8        311
IND_FOUR                       INDEX                       0        312          8        319
IND_THREE                      INDEX                       1        320          8        327
TST3                           TABLE                       1        328          8        335
IND_THREE                      INDEX                       2        336          8        343
IND_THREE                      INDEX                       3        344          8        351
TST3                           TABLE                       2        352          8        359
IND_THREE                      INDEX                       4        360          8        367
TST3                           TABLE                       3        368          8        375
IND_THREE                      INDEX                       5        376          8        383
TST2                           TABLE                      16        384        128        511
…….
TST2                           TABLE                      80       9472       1024      10495
IND_THREE                      INDEX                       6      10496          8      10503
TST3                           TABLE                       4      10504          8      10511
IND_THREE                      INDEX                       7      10512          8      10519
IND_THREE                      INDEX                       8      10520          8      10527
TST3                           TABLE                       5      10528          8      10535
SQL> alter table tst2 move tablespace f;
Table altered.
SQL> @seg
SEGMENT_NAME                   SEGMENT_TYPE        EXTENT_ID   BLOCK_ID     BLOCKS   ENDBLOCK
—————————— —————— ———- ———- ———- ———-
IND_THREE                      INDEX                       9        128          8        135
TST2                           TABLE                       0        136          8        143

TST2                           TABLE                       3        160          8        167
TST3                           TABLE                       0        296          8        303
IND_THREE                      INDEX                       0        304          8        311
IND_FOUR                       INDEX                       0        312          8        319
IND_THREE                      INDEX                       1        320          8        327
TST3                           TABLE                       1        328          8        335
IND_THREE                      INDEX                       2        336          8        343
IND_THREE                      INDEX                       3        344          8        351
TST3                           TABLE                       2        352          8        359
IND_THREE                      INDEX                       4        360          8        367
TST3                           TABLE                       3        368          8        375
IND_THREE                      INDEX                       5        376          8        383
IND_THREE                      INDEX                       6      10496          8      10503
TST3                           TABLE                       4      10504          8      10511
IND_THREE                      INDEX                       7      10512          8      10519
IND_THREE                      INDEX                       8      10520          8      10527
TST3                           TABLE                       5      10528          8      10535
TST2                           TABLE                       4      10536          8      10543
…..
TST2                           TABLE                      80      19840       1024      20863
98 rows selected.

The original table occupied space between 384 and 10495. Oracle copied the data to space 10536 to 20863 before dropping the  old segments. There’s the cause of the high increase in unused blocks. We therefore increased the table fragmentation in the datafile by re-organising.

To conclude, if you have any doubts left, lets drop everything but tst2.

SQL> drop table tst3 purge;
Table dropped.
SQL> @seg
SEGMENT_NAME                   SEGMENT_TYPE        EXTENT_ID   BLOCK_ID     BLOCKS   ENDBLOCK
—————————— —————— ———- ———- ———- ———-
TST2                           TABLE                       0        136          8        143
TST2                           TABLE                       1        144          8        151
TST2                           TABLE                       2        152          8        159
TST2                           TABLE                       3        160          8        167
TST2                           TABLE                       4      10536          8      10543
TST2                           TABLE                       5      10544          8      10551
TST2                           TABLE                       6      10552          8      10559
TST2                           TABLE                       7      10560          8      10567
TST2                           TABLE                       8      10568          8      10575
TST2                           TABLE                       9      10576          8      10583
TST2                           TABLE                      10      10584          8      10591
TST2                           TABLE                      11      10592          8      10599
TST2                           TABLE                      12      10600          8      10607
TST2                           TABLE                      13      10608          8      10615
TST2                           TABLE                      14      10616          8      10623
TST2                           TABLE                      15      10624          8      10631
TST2                           TABLE                      16      10752        128      10879
TST2                           TABLE                      17      10880        128      11007
TST2                           TABLE                      18      11008        128      11135
TST2                           TABLE                      19      11136        128      11263
TST2                           TABLE                      20      11264        128      11391
TST2                           TABLE                      21      11392        128      11519
TST2                           TABLE                      22      11520        128      11647
TST2                           TABLE                      23      11648        128      11775
TST2                           TABLE                      24      11776        128      11903
TST2                           TABLE                      25      11904        128      12031
TST2                           TABLE                      26      12032        128      12159
TST2                           TABLE                      27      12160        128      12287
TST2                           TABLE                      28      12288        128      12415
TST2                           TABLE                      29      12416        128      12543
TST2                           TABLE                      30      12544        128      12671
TST2                           TABLE                      31      12672        128      12799
TST2                           TABLE                      32      12800        128      12927
TST2                           TABLE                      33      12928        128      13055
TST2                           TABLE                      34      13056        128      13183
TST2                           TABLE                      35      13184        128      13311
TST2                           TABLE                      36      13312        128      13439
TST2                           TABLE                      37      13440        128      13567
TST2                           TABLE                      38      13568        128      13695
TST2                           TABLE                      39      13696        128      13823
TST2                           TABLE                      40      13824        128      13951
TST2                           TABLE                      41      13952        128      14079
TST2                           TABLE                      42      14080        128      14207
TST2                           TABLE                      43      14208        128      14335
TST2                           TABLE                      44      14336        128      14463
TST2                           TABLE                      45      14464        128      14591
TST2                           TABLE                      46      14592        128      14719
TST2                           TABLE                      47      14720        128      14847
TST2                           TABLE                      48      14848        128      14975
TST2                           TABLE                      49      14976        128      15103
TST2                           TABLE                      50      15104        128      15231
TST2                           TABLE                      51      15232        128      15359
TST2                           TABLE                      52      15360        128      15487
TST2                           TABLE                      53      15488        128      15615
TST2                           TABLE                      54      15616        128      15743
TST2                           TABLE                      55      15744        128      15871
TST2                           TABLE                      56      15872        128      15999
TST2                           TABLE                      57      16000        128      16127
TST2                           TABLE                      58      16128        128      16255
TST2                           TABLE                      59      16256        128      16383
TST2                           TABLE                      60      16384        128      16511
TST2                           TABLE                      61      16512        128      16639
TST2                           TABLE                      62      16640        128      16767
TST2                           TABLE                      63      16768        128      16895
TST2                           TABLE                      64      16896        128      17023
TST2                           TABLE                      65      17024        128      17151
TST2                           TABLE                      66      17152        128      17279
TST2                           TABLE                      67      17280        128      17407
TST2                           TABLE                      68      17408        128      17535
TST2                           TABLE                      69      17536        128      17663
TST2                           TABLE                      70      17664        128      17791
TST2                           TABLE                      71      17792        128      17919
TST2                           TABLE                      72      17920        128      18047
TST2                           TABLE                      73      18048        128      18175
TST2                           TABLE                      74      18176        128      18303
TST2                           TABLE                      75      18304        128      18431
TST2                           TABLE                      76      18432        128      18559
TST2                           TABLE                      77      18560        128      18687
TST2                           TABLE                      78      18688        128      18815
TST2                           TABLE                      79      18816       1024      19839
TST2                           TABLE                      80      19840       1024      20863
81 rows selected.
SQL> select maxblock-sblocks-128 from (select sum(blocks) sblocks from dba_extents where tablespace_name = ‘F’) a,
2  (select max(block_id+blocks) maxblock from dba_extents where tablespace_name = ‘F’) b;
MAXBLOCK-SBLOCKS-128
——————–
10496

There’s more unoccupied space in the datafile then occupied.

SQL> alter table tst2 move tablespace f;
Table altered.
SQL> @seg
SEGMENT_NAME                   SEGMENT_TYPE        EXTENT_ID   BLOCK_ID     BLOCKS   ENDBLOCK
—————————— —————— ———- ———- ———- ———-
TST2                           TABLE                       0        128          8        135
TST2                           TABLE                       1        168          8        175
TST2                           TABLE                       2        176          8        183
TST2                           TABLE                       3        184          8        191
TST2                           TABLE                       4        192          8        199
TST2                           TABLE                       5        200          8        207
TST2                           TABLE                       6        208          8        215
TST2                           TABLE                       7        216          8        223
TST2                           TABLE                       8        224          8        231
TST2                           TABLE                       9        232          8        239
TST2                           TABLE                      10        240          8        247
TST2                           TABLE                      11        248          8        255
TST2                           TABLE                      16        256        128        383
TST2                           TABLE                      17        384        128        511
TST2                           TABLE                      18        512        128        639
TST2                           TABLE                      19        640        128        767
TST2                           TABLE                      20        768        128        895
TST2                           TABLE                      21        896        128       1023
TST2                           TABLE                      22       1024        128       1151
TST2                           TABLE                      23       1152        128       1279
TST2                           TABLE                      24       1280        128       1407
TST2                           TABLE                      25       1408        128       1535
TST2                           TABLE                      26       1536        128       1663
TST2                           TABLE                      27       1664        128       1791
TST2                           TABLE                      28       1792        128       1919
TST2                           TABLE                      29       1920        128       2047
TST2                           TABLE                      30       2048        128       2175
TST2                           TABLE                      31       2176        128       2303
TST2                           TABLE                      32       2304        128       2431
TST2                           TABLE                      33       2432        128       2559
TST2                           TABLE                      34       2560        128       2687
TST2                           TABLE                      35       2688        128       2815
TST2                           TABLE                      36       2816        128       2943
TST2                           TABLE                      37       2944        128       3071
TST2                           TABLE                      38       3072        128       3199
TST2                           TABLE                      39       3200        128       3327
TST2                           TABLE                      40       3328        128       3455
TST2                           TABLE                      41       3456        128       3583
TST2                           TABLE                      42       3584        128       3711
TST2                           TABLE                      43       3712        128       3839
TST2                           TABLE                      44       3840        128       3967
TST2                           TABLE                      45       3968        128       4095
TST2                           TABLE                      46       4096        128       4223
TST2                           TABLE                      47       4224        128       4351
TST2                           TABLE                      48       4352        128       4479
TST2                           TABLE                      49       4480        128       4607
TST2                           TABLE                      50       4608        128       4735
TST2                           TABLE                      51       4736        128       4863
TST2                           TABLE                      52       4864        128       4991
TST2                           TABLE                      53       4992        128       5119
TST2                           TABLE                      54       5120        128       5247
TST2                           TABLE                      55       5248        128       5375
TST2                           TABLE                      56       5376        128       5503
TST2                           TABLE                      57       5504        128       5631
TST2                           TABLE                      58       5632        128       5759
TST2                           TABLE                      59       5760        128       5887
TST2                           TABLE                      60       5888        128       6015
TST2                           TABLE                      61       6016        128       6143
TST2                           TABLE                      62       6144        128       6271
TST2                           TABLE                      63       6272        128       6399
TST2                           TABLE                      64       6400        128       6527
TST2                           TABLE                      65       6528        128       6655
TST2                           TABLE                      66       6656        128       6783
TST2                           TABLE                      67       6784        128       6911
TST2                           TABLE                      68       6912        128       7039
TST2                           TABLE                      69       7040        128       7167
TST2                           TABLE                      70       7168        128       7295
TST2                           TABLE                      71       7296        128       7423
TST2                           TABLE                      72       7424        128       7551
TST2                           TABLE                      73       7552        128       7679
TST2                           TABLE                      74       7680        128       7807
TST2                           TABLE                      75       7808        128       7935
TST2                           TABLE                      76       7936        128       8063
TST2                           TABLE                      77       8064        128       8191
TST2                           TABLE                      78       8192        128       8319
TST2                           TABLE                      79       8320       1024       9343
TST2                           TABLE                      80       9344       1024      10367
TST2                           TABLE                      12      10496          8      10503
TST2                           TABLE                      13      10504          8      10511
TST2                           TABLE                      14      10512          8      10519
TST2                           TABLE                      15      10520          8      10527
81 rows selected.
SQL> select maxblock-sblocks-128 from (select sum(blocks) sblocks from dba_extents where tablespace_name = ‘F’) a,
2  (select max(block_id+blocks) maxblock from dba_extents where tablespace_name = ‘F’) b;
MAXBLOCK-SBLOCKS-128
——————–
160

Let’s try one more thing, supposing a table was highly spread with little data in it. Will it help to re-organise ?

SQL> select count(*) from tst2;
COUNT(*)
———-
9999
SQL> delete from tst2 where rownum < 9000;
8999 rows deleted.
SQL> commit;
Commit complete

The segment query returns exactly the same display as before we deleted, oracle does not re-organise for you.

SQL> alter table tst2 move tablespace f;
Table altered.
SQL> @seg
SEGMENT_NAME                   SEGMENT_TYPE        EXTENT_ID   BLOCK_ID     BLOCKS   ENDBLOCK
—————————— —————— ———- ———- ———- ———-
TST2                           TABLE                       0        136          8        143
TST2                           TABLE                       1        144          8        151
TST2                           TABLE                       2        152          8        159
TST2                           TABLE                       3        160          8        167
TST2                           TABLE                      16      10368        128      10495
TST2                           TABLE                       4      10528          8      10535
TST2                           TABLE                       5      10536          8      10543
TST2                           TABLE                       6      10544          8      10551
TST2                           TABLE                       7      10552          8      10559
TST2                           TABLE                       8      10560          8      10567
TST2                           TABLE                       9      10568          8      10575
TST2                           TABLE                      10      10576          8      10583
TST2                           TABLE                      11      10584          8      10591
TST2                           TABLE                      12      10592          8      10599
TST2                           TABLE                      13      10600          8      10607
TST2                           TABLE                      14      10608          8      10615
TST2                           TABLE                      15      10616          8      10623
TST2                           TABLE                      17      10624        128      10751
TST2                           TABLE                      18      10752        128      10879
TST2                           TABLE                      19      10880        128      11007
TST2                           TABLE                      20      11008        128      11135
TST2                           TABLE                      21      11136        128      11263
TST2                           TABLE                      22      11264        128      11391
23 rows selected.
SQL> select maxblock-sblocks-128 from (select sum(blocks) sblocks from dba_extents where tablespace_name = ‘F’) a,
2  (select max(block_id+blocks) maxblock from dba_extents where tablespace_name = ‘F’) b;
MAXBLOCK-SBLOCKS-128
——————–
10240

And that’s with 90% of the data deleted from the table. We’ve actually made the situation worse, the datafile has a high end of 11391 now, before with all the data in there we were at 10527.

The long and the short of this is that you don’t have great control over where segments are placed in a datafile. Checking the file for contiguous blocks and re-organising when there appears to be fragmentation will not always assist in freeing space in a datafile.

 

This entry was posted in Configuration., Oracle and tagged , , , , . Bookmark the permalink.