2

I have partitioned table by day with compressed query high option for partitions in Oracle 11.2 database.

Delete by key and direct insert was used to populate a data for the table. So the table is fragmented currently.

As I know from Oracle documentation the shrink space can not be applied to compressed tables.

I performed next actions

alter table order nocompress;
alter table order enable row movement;
alter table order MODIFY PARTITION SYS_P21674395 nocompress;
....

Also checked the autoextensible for table space

select tablespace_name, file_name, autoextensible from dba_data_files
where tablespace_name='DEV_ODS_DATA'

DEV_ODS_DATA datafile/dev_ods_data.878.1079624941 YES

select * from dba_tab_partitions where table_name='order';

all partitions compression is disabled

also

select iot_type,compression from user_tables where table_name='order';

iot_type=NULL; compression=NULL

When I trying to perform

ALTER TABLE order SHRINK SPACE compact;

or

ALTER TABLE order MODIFY PARTITION SYS_P21674395 SHRINK SPACE;  

I get the next error

ALTER TABLE order MODIFY PARTITION SYS_P21674395 SHRINK SPACE
Error report -
ORA-10635: Invalid segment or tablespace type
10635. 00000 -  "Invalid segment or tablespace type"
*Cause:    Cannot shrink the segment because it is not in auto segment space
           managed tablespace or it is not a data, index or lob segment.
*Action:   Check the tablespace and segment type and reissue the statement

The table does not have FUNCTION based indexes

Do the exists approach to shrink space for the table without table recreating?

1

2 Answers 2

3

NOCOMPRESS does not decompress existing data in a table/partition, it applies only to new data inserted later. You can leave original compression method unchanged.

You can MOVE a partition:

ALTER TABLE order MOVE PARTITION SYS_P21674395 UPDATE INDEXES;

This is not a fully online operation, meaning the data in the partition can not be modified during the move.

If you were on version 12.1 or higher, you could use MOVE ONLINE:

ALTER TABLE order MOVE PARTITION SYS_P21674395 ONLINE UPDATE INDEXES;

MOVE will copy and recompress (given that the compression method was set) the partition then drop the old segment.

You can also specify the compression method in the MOVE command:

ALTER TABLE order MOVE PARTITION SYS_P21674395 
  COMPRESS FOR QUERY HIGH UPDATE INDEXES;
3
  • OP may not have Exadata or IM, so "FOR QUERY HIGH" wouldn't work for them.
    – Paul W
    Feb 27 at 14:09
  • @PaulW In the first sentence in the question I have partitioned table by day with compressed query high option. Feb 27 at 14:25
  • Ah, yes, thank you. Missed that.
    – Paul W
    Feb 27 at 14:37
1

I found a solution

-- uncompress partition
  ALTER TABLE DEV_DW.TEST_TABLE move PARTITION SYS_P21822227 NOCOMPRESS UPDATE INDEXES;  

--required for shrink space
  ALTER TABLE TEST_TABLE enable row movement;

--Shrink the partition to reclaim unused space
ALTER TABLE TEST_TABLE MODIFY PARTITION SYS_P21822227 SHRINK SPACE;


--compress partition
ALTER TABLE DEV_DW.TEST_TABLE move PARTITION SYS_P21822227 COMPRESS FOR QUERY HIGH  UPDATE INDEXES; 

--gather stats
 BEGIN
DBMS_STATS.GATHER_TABLE_STATS('DEV_DW', 'TEST_TABLE',
                                     estimate_percent=>dbms_stats.auto_sample_size,
                                     block_sample=>TRUE,
                                     degree=>8) ;
END;
commit;

--test

  select 
  table_owner
  ,table_name
  ,partition_name
  ,high_value
  ,compression
  ,compress_for
  ,avg_row_len
  ,round(((blocks*16/1024)),2)/1024 "TOTAL_SIZE_GB" --The amount of space used by the partition in gigabytes.
  ,round((num_rows*avg_row_len/1024/1024),2)/1024 "ACTUAL_SIZE_GB" -- The amount of space used by the partition in gigabytes, calculated based on the number of rows and the average row length.
  ,round(((blocks*16/1024)-(num_rows*avg_row_len/1024/1024)),2)/1024 "FRAGMENTED_SPACE_GB" --The amount of space that is not used by the partition, in gigabytes.
  ,decode(round(((blocks*16/1024)),2),0,0, (round(((blocks*16/1024)-(num_rows*avg_row_len/1024/1024)),2)/round(((blocks*16/1024)),2))*100) "percentage" --The percentage of unused space in the partition, calculated by dividing the unused space by the total space and multiplying by 100. 
from dba_tab_partitions 
WHERE 
1=1
and table_owner='DEV_DW'
and table_name='TEST_TABLE'
and partition_name='SYS_P21822227'
and round(((blocks*16/1024)-(num_rows*avg_row_len/1024/1024)),2)/1024 > 0
order by 6 desc
;
5
  • It makes no sense to do this. Just ALTER TABLE DEV_DW.TEST_TABLE move PARTITION SYS_P21822227 UPDATE INDEXES; will do it. There is no need to do 2 MOVE + 1 SHRINK operations. Mar 9 at 12:50
  • @BalazsPapp why shink space is not required?
    – Banan904
    Mar 9 at 13:24
  • As I have already written: MOVE alone copies and recompresses the partition. Mar 9 at 13:57
  • @BalazsPapp ok then question next. Does the move command reorganize blocks and makes defragmentation as well?
    – Banan904
    Mar 10 at 13:18
  • MOVE creates a new copy of the segment, compresses and reorganizes data, then drops the old segment. Mar 10 at 22:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.