oracle move表释放空间

本文详细阐述了当表经过大量DML操作后,高水位线不下降的情况,通过使用altertablemove方法释放空间。文章还提供了解决过程中遇到的问题分析和解决步骤,包括检查表大小、记录数、DDL语句,以及如何调整INITIAL参数来释放更多空间。最后,通过展示查询结果,验证了解决方案的有效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 场景:

定时任务查询一张表速度超级慢,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

 

### 如何在 Oracle 数据库释放未使用的空间 #### 查询当前空间的使用情况 为了有效管理空间释放未使用的部分,首先需要了解当前空间的状态。可以通过以下 SQL 查询来获取详细的空间信息: ```sql -- 查看所有空间的使用情况 SELECT a.tablespace_name AS "空间名", total AS "空间大小", free AS "空间剩余大小", (total - free) AS "空间使用大小", total / (1024 * 1024 * 1024) AS "空间大小(G)", free / (1024 * 1024 * 1024) AS "空间剩余大小(G)", (total - free) / (1024 * 1024 * 1024) AS "空间使用大小(G)", ROUND((total - free) / total, 4) * 100 AS "使用率%" FROM ( SELECT tablespace_name, SUM(bytes) free FROM dba_free_space GROUP BY tablespace_name ) a, ( SELECT tablespace_name, SUM(bytes) total FROM dba_data_files GROUP BY tablespace_name ) b WHERE a.tablespace_name = b.tablespace_name ORDER BY "使用率%" DESC; ``` 此查询可以帮助识别哪些空间存在大量可用空间[^2]。 --- #### 清理和回收未使用的对象 对于某些情况下存在的已删除但尚未被实际清理的对象(即所谓的“孤儿段”),可以采取以下措施: 1. **清空无用的数据段** 如果某个再需要或者其数据已经过期,则可以直接通过 `TRUNCATE` 命令快速清除该的内容及其关联的空间分配: ```sql TRUNCATE TABLE schema_name.table_name CASCADE CONSTRAINTS; ``` 此命令仅会移除所有的记录,还会重置高水位线(HWM),从而允许操作系统重新利用之前由这些记录占据的部分磁盘资源[^2]。 2. **移动大到新的存储位置** 对于那些仍然保留有重要业务逻辑却占据了过多物理文件容量的大格来说,“MOVE”操作是一个错的选择方案之一。它能够有效地将原始数据迁移到另一个更高效的地方去存放,同时也会自动调整相应的索引结构以便维持正常运转状态。 ```sql ALTER TABLE schema_name.table_name MOVE TABLESPACE new_tablespace_name; ``` 这一过程可能会涉及到重建相关的二级索引等工作项,因此建议事先做好充分准备再实施具体动作[^2]。 3. **收缩临时空间** 针对因排序、创建索引等活动而暂时借用过的临时区域,在完成相应事务之后通常会被立即归还给系统池子供后续其他进程调用;但如果发现长时间以来始终保持着较高的占用水平的话,则可能意味着存在问题亟待解决——比如长期运行的任务未能结束或者是配置参数设置当所致等等原因引起的现象。此时可通过如下方式尝试优化处理: - 修改初始化参数以减少默认分配量; ```sql ALTER SYSTEM SET TEMPORARY_TABLESPACE='TEMP'; ``` - 手动缩小现有tempfile尺寸范围直至满足需求为止: ```sql ALTER DATABASE TEMPFILE '/path/to/temp/file.dbf' RESIZE TO smaller_size MB; ``` --- #### 总结注意事项 尽管上述方法均有助于缓解甚至彻底消除必要的浪费现象发生,但在实际应用过程中仍需谨慎行事以免造成可逆的影响后果出现。务必提前备份好关键资料以防万一出现问题时有所挽回余地,并且密切监控整个变更期间的各项指标变化趋势确保一切都在掌控之中[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值