场景:
定时任务查询一张表速度超级慢,delete很多记录之后数据还是很慢
,加上索引之后依旧慢。
执行方法:
alter table T_DMS_04 move tablespace JAC_PCL_DATA;
参考文档:======================
有好多时候,表经过大量的DML操作后,高水线也会升高,在delete后高水位线还是没下来,
也就是说,数据是删除了,但空间并没有释放,这时候我们可以用alter table move的方法
使空间释放,但曾有一次,对表进行MOVE后,空间还是没有释放,
下面我就把解决过程模拟一下,就知道之所在了
--看一下下面两张表的大小 SQL> select SEGMENT_NAME,BYTES/1024/1024 M from user_segments where SEGMENT_NAME like 'TEST_TB%'; SEGMENT_NAME M -------------------- ---------- TEST_TB1 1088 TEST_TB2 1088 --查看记录数 SQL> select count(*) from TEST_TB1; COUNT(*) ---------- 0 SQL> select count(*) from TEST_TB2; COUNT(*) ---------- 0 --可以看到两张表均为空表,现在对两张表都进行move操作 SQL> alter table TEST_TB2 move; Table altered. SQL> alter table TEST_TB1 move; Table altered. --再看两张表所占用的空间 SQL> select SEGMENT_NAME,BYTES/1024/1024 M from user_segments where SEGMENT_NAME like 'TEST_TB%'; SEGMENT_NAME M -------------------- ---------- TEST_TB1 1024 TEST_TB2 .0625 --为什么会这样,我们想到了空间分配问题,于是查看两表的DDL语句 SQL> set long 20000 SQL> SELECT DBMS_METADATA.GET_DDL('TABLE','TEST_TB2') FROM USER_TABLES; DBMS_METADATA.GET_DDL('TABLE','TEST_TB2') ----------------------------------------------------------- CREATE TABLE "LZDYXIN"."TEST_TB2" ( "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 "LZDYXIN" SQL> SELECT DBMS_METADATA.GET_DDL('TABLE','TEST_TB1') FROM USER_TABLES; DBMS_METADATA.GET_DDL('TABLE','TEST_TB1') ----------------------------------------------------------------------- CREATE TABLE "LZDYXIN"."TEST_TB1" ( "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 "LZDYXIN"
由上面的DDL发现,Test_tb1的INITIAL 1073741824,可以看出move减少空间时不会
小于表的初始扩展,所以我们可以在move时重新指定表的INITIAL参数
SQL> alter table TEST_TB1 move storage(initial 64K); Table altered. SQL> col SEGMENT_NAME format a20 SQL> select SEGMENT_NAME,BYTES/1024/1024 M from user_segments where SEGMENT_NAME like 'TEST_TB%'; SEGMENT_NAME M -------------------- ---------- TEST_TB1 .0625 TEST_TB2 .0625
--查看一个表所占的空间大小: SELECT bytes/1024/1024 ||'MB' TABLE_SIZE ,u.* FROM USER_SEGMENTS U WHERE U.SEGMENT_NAME='JK_TEST'; --查看一个表空间所占的实际大小: SELECT SUM(BYTES) / 1024 / 1024 ||'MB' FROM USER_SEGMENTS U WHERE TABLESPACE_NAME = 'DATA01'; --查看一个表空间对应的数据文件: SELECT * FROM DBA_DATA_FILES D WHERE D.TABLESPACE_NAME = 'DATA01'; --查看表空间的使用情况: SELECT A.TABLESPACE_NAME, FILENUM, TOTAL "TOTAL (MB)", F.FREE "FREE (MB)", TO_CHAR(ROUND(FREE * 100 / TOTAL, 2), '990.00') "FREE%", TO_CHAR(ROUND((TOTAL - FREE) * 100 / TOTAL, 2), '990.00') "USED%", ROUND(MAXSIZES, 2) "MAX (MB)" FROM (SELECT TABLESPACE_NAME, COUNT(FILE_ID) FILENUM, SUM(BYTES / (1024 * 1024)) TOTAL, SUM(MAXBYTES) / 1024 / 1024 MAXSIZES FROM DBA_DATA_FILES GROUP BY TABLESPACE_NAME) A, (SELECT TABLESPACE_NAME, ROUND(SUM(BYTES / (1024 * 1024))) FREE FROM DBA_FREE_SPACE GROUP BY TABLESPACE_NAME) F WHERE A.TABLESPACE_NAME = F.TABLESPACE_NAME --查看数据文件的实际使用情况: SELECT CEIL(MAX_BLOCK * BLOCK_SIZE / 1024) FROM (SELECT MAX(BLOCK_ID) MAX_BLOCK FROM DBA_EXTENTS WHERE FILE_ID IN (SELECT FILE_ID FROM DBA_DATA_FILES D WHERE D.TABLESPACE_NAME = 'USERS')) M, (SELECT VALUE / 1024 BLOCK_SIZE FROM V$PARAMETER WHERE NAME = 'db_block_size') B
http://blog.sina.com.cn/s/blog_62d1205301013cg7.html