可以用来收缩段,消除空间碎片的方法有两种: 1.alter table table_name move 需要注意: 1)move操作会锁表。(如果是很小的表,可以在线做。如果是大表一定要注意,会长时间锁表,只能查询,影响正常业务运行。) 2)move操作会使索引失效,一定要rebuild。(因为move操作会改变一些记录的ROWID,所以MOVE之后索引会变为无效,需要REBUILD。) 2.使用shrink space alter table table_name shrink space 前提条件 1) 必须启用行记录转移(enable row movement) 2) 仅仅适用于堆表,且位于自动段空间管理的表空间(堆表包括:标准表,分区表,物化视图容器,物化视图日志表) 优点: 提高缓存利用率,提高OLTP的性能 减少磁盘I/O,提高访问速度,节省磁盘空间 段收缩是在线的,索引在段收缩期间维护,不要求额外的磁盘空间加参数 cascade: 缩小表及其索引,并移动高水位线,释放空间 compact: 仅仅是缩小表和索引,并不移动高水位线,不释放空间如果在业务繁忙时做压缩,可以使用alter table shrink space compact来对表格进行碎片整理,而不调整高水位线,之后再次调用alter table table_name shrink space来释放空间。也可以使用alter table table_name shrink space cascade来同时对索引都进行收缩,这等同于同时执行alter index idxname shrink space。 方法一:move方式收缩表 1)创建一张新表test,并插入数据
SQL>
create
table
TEST (id
int
,
name
char
(2000)) tablespace users;
Table
created.
SQL>
insert
into
TEST
values
(1,
'aa'
);
SQL>
insert
into
TEST
values
(2,
'bb'
);
SQL>
insert
into
TEST
values
(3,
'cc'
);
--查看test表中rowid
SQL>
select
Dbms_Rowid.rowid_block_number(rowid)
from
TEST;
2) 删除表中部分数据,并再次查看表中rowid
SQL>
delete
from
TEST
where
mod(id,2)=1;
SQL>
select
Dbms_Rowid.rowid_block_number(rowid)
from
TEST;
3) 对表执行move操作
SQL>
alter
table
TEST
move
;
4)再次查看表中rowid
SQL>
select
Dbms_Rowid.rowid_block_number(rowid)
from
TEST;
小结:
1
move操作后,数据的rowid发生了改变,我们知道,index是通过rowid来获取数据行的,所以table上的index是必须要rebuild的。
5)
查看表中索引情况,此时索引为失效的
SQL> select index_name,status from user_indexes where index_name='TEST_INDEX';
INDEX_NAME STATUS
------------------------------ --------
TEST_INDEX UNUSABLE
6)在线重建索引
SQL>
alter
index
TEST_MOVE_INDEX rebuild online;
小结:2
move操作后,表中索引会失效
--查看锁情况
SQL> SELECT b.session_id AS sid, NVL(b.oracle_username, '(oracle)') AS username, a.owner AS object_owner, a.object_name, Decode(b.locked_mode, 0, 'None', 1, 'Null (NULL)', 2, 'Row-S (SS)', 3, 'Row-X (SX)', 4, 'Share (S)', 5, 'S/Row-X (SSX)', 6, 'Exclusive (X)', b.locked_mode) locked_mode, b.os_user_name FROM dba_objects a, v$locked_object b WHERE a.object_id = b.object_id;
SID USERNAME OBJECT_OWNER OBJECT_NAME LOCKED_MODE OS_USER_NAME---------- -------------------- ---------------------- ------------------- ----------------------- ----------------------- 33 YMM YMM TEST Exclusive (X) oracle
小结:3
--Exclusive (X) 是6号锁,独占锁。
--这就意味着,table在进行move操作时,我们只能对它进行select的操作。
也就是说当我们的一个session对table进行DML操作且没有commit时,在另一个session中是不能对这个table进行move操作的,
否则oracle会返回这样的错误信息:ORA-00054 。
SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/1024 init from user_segments where SEGMENT_NAME='TEST';
SEGMENT_NAME EXTENTS BLOCKS INIT
------------------------ ---------- ---------- --------
TEST 3 1280 10
--TEST表初始分配了10M的空间,1280个BLOCKS。
SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name='TEST';
TABLE_NAME BLOCKS EMPTY_BLOCKS
----------------------- ---------- -------------------
TEST
--USER_TABLES视图显示有0个使用的BLOCKS,1280个空闲BLOCKS。
--向表中插入数据
SQL> insert into TEST select * from information;
SQL> analyze table TEST compute statistics;
SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/1024 init from user_segments where SEGMENT_NAME='TEST';
SEGMENT_NAME EXTENTS BLOCKS INIT
----------------------- ---------- ---------- ----------
TEST 3 1280 10
SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name='TEST';
TABLE_NAME BLOCKS EMPTY_BLOCKS
------------------------------ ---------- ------------
TEST 1006 274
--插入数据后,分配的空间仍不变,因为10M还没使用完。显示使用了1006个BLOCKS,空闲274个BLOCKS。这时候的1006 BLOCKS即是高水位线。
SQL> commit;
SQL> select count(*) from test;
COUNT(*)
----------
122513
SQL> delete from test where rownum<=50000;
SQL> analyze table test compute statistics;
SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/1024 init from user_segments where SEGMENT_NAME='TEST';
SEGMENT_NAME EXTENTS BLOCKS INIT
------------------------- --------------- ---------- ----------
TEST 3 1280 10
SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name='TEST';
TABLE_NAME BLOCKS EMPTY_BLOCKS
------------------------------ ---------- ------------
TEST 1006 274
SQL> select count(distinct dbms_rowid.rowid_block_number(rowid)) used_blocks from test;
USED_BLOCKS
-----------
573
--这边可以看到,删掉部分数据后,仍然显示使用了1006个BLOCKS,高水位没变。但查询真正使用的BLOCK数只有573个。所以DELETE操作是不会改变HWM的。
SQL> alter table TEST move;
SQL> analyze table TEST compute statistics;
SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/1024 init from user_segments where SEGMENT_NAME='TEST';
SEGMENT_NAME EXTENTS BLOCKS INIT
-------------------------- -------------- ---------- ----------
TEST 3 1280 10
SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name='TEST';
TABLE_NAME BLOCKS EMPTY_BLOCKS
------------------- ---------- ------------
TEST 592 688
小结:4
--MOVE之后,HWM降低了,空闲块也上去了。
--但是分配的空间并没有改变,仍然是1280个BLOCKS。
方法二:shrink space方式收缩表
SQL> delete from test where rownum<=50000;
--首先设置允许行迁移
SQL> alter table TEST enable row movement;
SQL> alter table TEST shrink space;
SQL> analyze table TEST compute statistics; -->使用analyze更新统计信息后EMPTY_BLOCKS得到数据
SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/1024 init from user_segments where SEGMENT_NAME='TEST';
SEGMENT_NAME EXTENTS BLOCKS INIT
------------------------ ---------------- ---------- ----------
TEST 1 600 10
SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name='TEST';
TABLE_NAME BLOCKS EMPTY_BLOCKS
------------------------------ ---------- ------------
TEST 592 8
--SHRINK SPACE真正做到了对段的压缩,包括初始分配的也压了,所以它是回收高水位线操作。
验证cascade与compact的差异
--删除一些数据SQL> delete from test where rownum<8000; SQL> alter table test shrink space compact; -->使用compact方式收缩表段 SQL> exec show_space('TEST','SCOTT'); Unformatted Blocks ..................... 0 FS1 Blocks (0-25) ...................... 1 FS2 Blocks (25-50) ..................... 2 FS3 Blocks (50-75) ..................... 0 FS4 Blocks (75-100)..................... 103 Full Blocks ............................ 14,214 --仅有的变化为14318-14214=104块,即完全填满的数据块减少了104块Total Blocks............................ 14,488 --数据的总块数及总大小并没有减少,即未移动高水位线 Total Bytes............................. 118,685,696 Total MBytes............................ 113 Unused Blocks........................... 5 Unused Bytes............................ 40,960 Last Used Ext FileId.................... 4 Last Used Ext BlockId................... 16,521 Last Used Block......................... 147 PL/SQL procedure successfully completed. SQL> alter table test shrink space cascade; -->使用cascade方式收缩 SQL> exec show_space('TEST','SCOTT'); Unformatted Blocks ..................... 0 FS1 Blocks (0-25) ...................... 1 FS2 Blocks (25-50) ..................... 2 FS3 Blocks (50-75) ..................... 0 FS4 Blocks (75-100)..................... 0 Full Blocks ............................ 14,214 Total Blocks............................ 14,384 -->总块数及总大小均已减少 Total Bytes............................. 117,833,728 Total MBytes............................ 112 Unused Blocks........................... 4 Unused Bytes............................ 32,768 Last Used Ext FileId.................... 4 Last Used Ext BlockId................... 16,521 Last Used Block......................... 44 PL/SQL procedure successfully completed. -->收缩之后索引依然有效 SQL> select OWNER,INDEX_NAME,STATUS from dba_indexes where TABLE_NAME='TEST'; OWNER INDEX_NAME STATUS --------------- -------------------- ------------ SCOTT idx_test VALID
小结:
compact:仅仅是缩小表和索引,并不移动高水位线,不释放空间
cascade:缩小表及其索引,并移动高水位线,释放空间
语法总结:ALTER TABLE <table_name> ENABLE ROW MOVEMENT -->前提条件 ALTER TABLE <table_name> SHRINK SPACE [ <NULL> | COMPACT | CASCADE ]; ALTER TABLE <table_name> SHRINK SPACE COMPCAT; -->缩小表和索引,不移动高水位线,不释放空间 ALTER TABLE <table_name> SHRINK SPACE; -->收缩表,降低高水位线; ALTER TABLE <table_name> SHRINK SPACE CASCADE; -->收缩表,降低高水位线,并且相关索引也要收缩一下 ALTER TABLE <table_name> MODIFY LOB (lob_column) (SHRINK SPACE); -->收缩LOB段 ALTER INDEX IDXNAME SHRINK SPACE;
编辑推荐:
下一篇:
相关推荐
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
热文推荐
- Oracle日常问题-坏块修复
Oracle日常问题-坏块修复
26-03-03
- Oracle的并行
Oracle的并行
26-03-03
- 江波龙 MWC26 巴塞罗那展示 HLC UFS 与 pTLC UFS 嵌入式闪存解决方案
- 美团旗下 AI 浏览器涉嫌抄袭代码?官方回应称充分尊重原作者,已移除相关项目
- 佳能携手 Synopsys 开发 2nm 图像处理芯片,代工委单 Rapidus
- 特斯拉纵火案嫌疑人认罪,或将面临最高 70 年监禁
特斯拉纵火案嫌疑人认罪,或将面临最高 70 年监禁
26-03-03
- ORA-27468: ""."" IS LOCKED BY ANOTHER PROCESS
- Oracle轻量级实时监控工具-oratop
Oracle轻量级实时监控工具-oratop
26-03-03
- Oracle Database 20c 官方文档以及云端版本已发布
Oracle Database 20c 官方文档以及云端版本已发布
26-03-03
- DB2数据库适配NC65
DB2数据库适配NC65
26-03-03
