发表于: 2008.08.20 23:44
分类: ORACLE
出处: http://yangtingkun.itpub.net/post/468/469123
---------------------------------------------------------------
如果表的高水位线比较高,或者表经历了大数据量的产生操作,经常会使用ALTER TABLE MOVE的方法来减少表占用的空间。
不过今天才发现以前对MOVE的了解一直存在偏差。
看一个简单的例子:
两张表几乎一样大,而且都是空表。但是通过MOVE之后,得到的结果却完全不同。
SQL> SELECT SEGMENT_NAME, BYTES/1024/1024/1024 G
2 FROM USER_SEGMENTS
3 WHERE SEGMENT_NAME LIKE 'T_BIG_TABLE%';
SEGMENT_NAME G
------------------------------ ----------
T_BIG_TABLE 1
T_BIG_TABLE2 1.3125
SQL> ALTER TABLE T_BIG_TABLE MOVE;
表已更改。
SQL> ALTER TABLE T_BIG_TABLE2 MOVE;
表已更改。
SQL> SELECT SEGMENT_NAME, BYTES/1024/1024/1024 G
2 FROM USER_SEGMENTS
3 WHERE SEGMENT_NAME LIKE 'T_BIG_TABLE%';
SEGMENT_NAME G
------------------------------ ----------
T_BIG_TABLE 1
T_BIG_TABLE2 .000061035
SQL> SELECT COUNT(*) FROM T_BIG_TABLE;
COUNT(*)
----------
0
SQL> SELECT COUNT(*) FROM T_BIG_TABLE2;
COUNT(*)
----------
0
造成这个现象的原因是由于T_BIT_TABLE表只包含的一个初始EXTENT,而这个EXTENT的大小是1G,而T_BIT_TABLE2则包含很多的64K大小的EXTENT。
SQL> SET LONG 10000
SQL> SELECT DBMS_METADATA.GET_DDL('TABLE', TABLE_NAME)
2 FROM USER_TABLES
3 WHERE TABLE_NAME LIKE 'T_BIG_TABLE%';
DBMS_METADATA.GET_DDL('TABLE',TABLE_NAME)
--------------------------------------------------------------------------------
CREATE TABLE "YANGTK"."T_BIG_TABLE2"
( "ID" NUMBER,
"NAME" VARCHAR2(30)
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "LOB_SPACE"
CREATE TABLE "YANGTK"."T_BIG_TABLE"
( "ID" NUMBER,
"NAME" VARCHAR2(30)
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 1073741824 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "LOB_SPACE"
也就是说MOVE操作会根据原表的INITIAL大小为新表建立第1个EXTENT。MOVE不会自动减少表的初始扩展的大小。
因此对于表T_BIG_TABLE这种情况,执行MOVE的时候应该指定新的存储参数:
SQL> ALTER TABLE T_BIG_TABLE MOVE STORAGE (INITIAL 1M);
表已更改。
SQL> SELECT SEGMENT_NAME, BYTES/1024/1024/1024 G
2 FROM USER_SEGMENTS
3 WHERE SEGMENT_NAME LIKE 'T_BIG_TABLE%';
SEGMENT_NAME G
------------------------------ ----------
T_BIG_TABLE .000976563
T_BIG_TABLE2 .000061035











