--表分配空间大小
select segment_name, bytes / 1024 / 1024
from user_segments a
where a.segment_name = 'TB_NAME';
--表实际占用空间大小
select num_rows * avg_row_len / 1024 / 1024
from user_tables
where table_name = 'TB_NAME';
--需要压缩的段
select to_number(a.reclaimable_space / a.allocated_space) rate,
replace(a.c3, '"', '') || ';' move_script,
replace(replace(a.c2, '"', '') || ';', 'COMPACT', '') shrink_script,
replace(a.c2, '"', '') || ';' busy_shrink_scripts,
a.*
from table(dbms_space.asa_recommendations()) a
where to_number(a.reclaimable_space / a.allocated_space) > 0.2
order by a.reclaimable_space / a.allocated_space desc;
--Shrink Segment能压缩数据段、整理数据碎片、降低高水位,以提高性能、节省空间。
--如遇到需要回收空间的,表空间可回收的最小值 参见reference dba_extents里block_id为start_block_id
select max(a.block_id+a.blocks)*8/1024 from dba_extents a where file_id = 8;
alter database datafile '/XXXXXX/xxxx.dbf' resize -- max(a.block_id+a.blocks)*8/1024 ;
--存在行迁移问题的objects(move之后对应对的索引需要重建)
select 'alter table ' || b.attr1 || '.' || b.attr2 || ' move pctfree XX;' move_script,
a.task_id,
a.type,
a.message,
a.more_info
from dba_advisor_findings a, dba_advisor_objects b
where a.task_id = b.task_id
and a.object_id = b.object_id
and a.message =
'The object has chained rows that can be removed by re-org.'
order by a.task_id desc;
--重建索引
SELECT STATUS,
'alter index ' || a.owner || '.' || a.index_name || ' rebuild;'
FROM DBA_INDEXES A
WHERE A.owner = 'xxx'
AND A.table_name = 'yyy';
alter table scott.emp shrink space 与 ALTER TABLE SCOTT.EMP MOVE 区别
1.都会去除hmw(高水位线),但 move 不会压缩分配的空间 注 :move可以通过制定storage参数做到真正压缩分配空间
2.使用 move 时会改变一些记录的 rowid,所以move后索引会变为无效,需要rebuild , 使用 shrink space 时,索引会自动维护
3.使用 shrink space 要先启用表的行迁移 ( alter table scott.emp enable row movement)
4.shrink space 需要在表空间是自动段空间管理的,所以system表空间上的表无法shrinkspace;
5.如果在业务繁忙时做压缩,可以先 shrink space compact,来压缩,shrink space cascade 会同时压缩索引
--block信息在统计信息收集完成后改变
SELECT A.BLOCKS,A.LAST_ANALYZED,A.* FROM USER_TABLES A WHERE A.TABLE_NAME = 'TB_NAME';
--block信息立即改变,同时 user_segments.blocks 一般大于user_table.blocks 差值为 segment_head占用的存储。
SELECT A.BLOCKS,A.* FROM USER_SEGMENTS A WHERE A.SEGMENT_NAME = 'TB_NAME';
select segment_name, bytes / 1024 / 1024
from user_segments a
where a.segment_name = 'TB_NAME';
--表实际占用空间大小
select num_rows * avg_row_len / 1024 / 1024
from user_tables
where table_name = 'TB_NAME';
--需要压缩的段
select to_number(a.reclaimable_space / a.allocated_space) rate,
replace(a.c3, '"', '') || ';' move_script,
replace(replace(a.c2, '"', '') || ';', 'COMPACT', '') shrink_script,
replace(a.c2, '"', '') || ';' busy_shrink_scripts,
a.*
from table(dbms_space.asa_recommendations()) a
where to_number(a.reclaimable_space / a.allocated_space) > 0.2
order by a.reclaimable_space / a.allocated_space desc;
--Shrink Segment能压缩数据段、整理数据碎片、降低高水位,以提高性能、节省空间。
--如遇到需要回收空间的,表空间可回收的最小值 参见reference dba_extents里block_id为start_block_id
select max(a.block_id+a.blocks)*8/1024 from dba_extents a where file_id = 8;
alter database datafile '/XXXXXX/xxxx.dbf' resize -- max(a.block_id+a.blocks)*8/1024 ;
--存在行迁移问题的objects(move之后对应对的索引需要重建)
select 'alter table ' || b.attr1 || '.' || b.attr2 || ' move pctfree XX;' move_script,
a.task_id,
a.type,
a.message,
a.more_info
from dba_advisor_findings a, dba_advisor_objects b
where a.task_id = b.task_id
and a.object_id = b.object_id
and a.message =
'The object has chained rows that can be removed by re-org.'
order by a.task_id desc;
--重建索引
SELECT STATUS,
'alter index ' || a.owner || '.' || a.index_name || ' rebuild;'
FROM DBA_INDEXES A
WHERE A.owner = 'xxx'
AND A.table_name = 'yyy';
alter table scott.emp shrink space 与 ALTER TABLE SCOTT.EMP MOVE 区别
1.都会去除hmw(高水位线),但 move 不会压缩分配的空间 注 :move可以通过制定storage参数做到真正压缩分配空间
2.使用 move 时会改变一些记录的 rowid,所以move后索引会变为无效,需要rebuild , 使用 shrink space 时,索引会自动维护
3.使用 shrink space 要先启用表的行迁移 ( alter table scott.emp enable row movement)
4.shrink space 需要在表空间是自动段空间管理的,所以system表空间上的表无法shrinkspace;
5.如果在业务繁忙时做压缩,可以先 shrink space compact,来压缩,shrink space cascade 会同时压缩索引
--block信息在统计信息收集完成后改变
SELECT A.BLOCKS,A.LAST_ANALYZED,A.* FROM USER_TABLES A WHERE A.TABLE_NAME = 'TB_NAME';
--block信息立即改变,同时 user_segments.blocks 一般大于user_table.blocks 差值为 segment_head占用的存储。
SELECT A.BLOCKS,A.* FROM USER_SEGMENTS A WHERE A.SEGMENT_NAME = 'TB_NAME';