如果表的高水位线比较高,或者表经历了大数据量的产生操作,经常会使用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 |