Oracle收缩表空间
可以使用 alter database datafile 'file path...' resize xM 的命令来缩小数据文件。
SELECT 'alter database datafile ''' || A.FILE_NAME || ''' resize ' || ROUND(A.FILESIZE - (A.FILESIZE - C.HWMSIZE - 100) * 0.8) || 'M;', A.FILESIZE || 'M' AS "数据文件的总大小", C.HWMSIZE || 'M' AS "数据文件的实用大小" FROM (SELECT FILE_ID, FILE_NAME, ROUND(BYTES / 1024 / 1024) AS FILESIZE FROM DBA_DATA_FILES) A, (SELECT FILE_ID, ROUND(MAX(BLOCK_ID) * 8 / 1024) AS HWMSIZE FROM DBA_EXTENTS GROUP BY FILE_ID) C WHERE A.FILE_ID = C.FILE_ID AND A.FILESIZE - C.HWMSIZE > 100;
or
SELECT 'alter database ' || A.NAME || ' datafile ''' || B.FILE_NAME || '''' || ' resize ' || GREATEST(TRUNC(BYTES_FULL / .7), (BYTES_TOTAL - BYTES_FREE)) || CHR(10) || '--tablespace was ' || TRUNC(BYTES_FULL * 100 / BYTES_TOTAL) || '% full now ' || TRUNC(BYTES_FULL * 100 / GREATEST(TRUNC(BYTES_FULL / .7), (BYTES_TOTAL - BYTES_FREE))) || '%' FROM V$DATABASE A, DBA_DATA_FILES B, (SELECT TABLESPACE_NAME, SUM(BYTES) BYTES_FULL FROM DBA_EXTENTS GROUP BY TABLESPACE_NAME) C, (SELECT TABLESPACE_NAME, SUM(BYTES) BYTES_TOTAL FROM DBA_DATA_FILES GROUP BY TABLESPACE_NAME) D, (SELECT A.TABLESPACE_NAME, A.FILE_ID, B.BYTES BYTES_FREE FROM (SELECT TABLESPACE_NAME, FILE_ID, MAX(BLOCK_ID) MAX_DATA_BLOCK_ID FROM DBA_EXTENTS GROUP BY TABLESPACE_NAME, FILE_ID) A, DBA_FREE_SPACE B WHERE A.TABLESPACE_NAME = B.TABLESPACE_NAME AND A.FILE_ID = B.FILE_ID AND B.BLOCK_ID > A.MAX_DATA_BLOCK_ID) E WHERE B.TABLESPACE_NAME = C.TABLESPACE_NAME AND B.TABLESPACE_NAME = D.TABLESPACE_NAME AND BYTES_FULL / BYTES_TOTAL < .7 AND B.TABLESPACE_NAME = E.TABLESPACE_NAME AND B.FILE_ID = E.FILE_ID;
alter tablespace TABLESPACENAME coalesce
此语句是整合表空间的碎片增加表空间的连续性,但是他不会收缩一个文件的大小的
选择某个表空间中超过N个blocks的segments,通过此语句可以看出那个表占用的空间大
SELECT OWNER, SEGMENT_NAME, SEGMENT_TYPE, BLOCKS FROM DBA_SEGMENTS WHERE TABLESPACE_NAME = 'RISK' AND BLOCKS > 1000 ORDER BY BLOCKS DESC;
分析表,得知表的一些信息
analyze table TABLENAME estimate statistics;
SELECT INITIAL_EXTENT, NEXT_EXTENT, MIN_EXTENTS, BLOCKS, EMPTY_BLOCKS FROM DBA_TABLES WHERE TABLE_NAME = 'xx' AND OWNER = 'xx';
用alter table ... deallocate unused 命令回收表的空间
alter table user.tablename deallocate unused keep 1k;