Oracle 刪除表中記錄 如何釋放表及表空間大小


1.查看一個表所占的空間大小:
SELECT bytes/1024/1024 ||'MB' TABLE_SIZE ,u.* FROM USER_SEGMENTS U WHERE U.SEGMENT_NAME='JK_TEST';
2.查看一個表空間所占的實際大小:
SELECT SUM(BYTES) / 1024 / 1024 ||'MB' FROM USER_SEGMENTS U  WHERE TABLESPACE_NAME = 'DATA01';
3.查看一個表空間對應的數據文件:
SELECT * FROM DBA_DATA_FILES D WHERE D.TABLESPACE_NAME = 'DATA01';
4.查看表空間的使用情況:
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
5.查看數據文件的實際使用情況:
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
一、創建一個有十萬條記錄的測試表jk_test ,查看其所占空間大小3873M
delete jk_test。再次查看大小不會變,此時執行select * from jk_test會發現速度超極慢,查詢結果卻是空,查看其COST,發現是10萬多。很難理解吧,其實是其所占空間沒有釋放的緣故。
執行alter table jk_test move 或 alter table jk_test move storage(initial 64k)
或alter table jk_test deallocate unused或 alter table jk_test shrink space.
注意:因為alter table jk_test move 是通過消除行遷移,清除空間碎片,刪除空閑空間,實現縮小所占的空間,但會導致此表上的索引無效(因為ROWID變了,無法找到),所以執行 move 就需要重建索引。
找到表對應的索引。
select index_name,table_name,tablespace_name,index_type,status  from dba_indexes  where table_owner='SCOTT' ;
根據status 的值,重建無效的就行了。
sql='alter index '||index_name||' rebuild'; 使用存儲過程執行,稍微安慰。
還要注意alter table move過程中會產生鎖,應該避免在業務高峰期操作!
再次查看其所占空間大小,發現已經很小了,再一次執行查詢,很快了吧。
另外說明:truncate table jk_test 會執行的更快,而且其所占的空間也會釋放,我想應該是truncate 語句執行后是不會進入oracle回收站(recylebin)的緣故。如果drop 一個表加上purge 也不會進回收站(在此里面的數據可以通過flashback找回)。
不管是delete還是truncate 相應數據文件的大小並不會改變,如果想改變數據文件所占空間大小可執行如下語句:alter database datafile 'filename' resize 8g重定義數據文件的大小(不能小於該數據文件已用空間的大小)。
另補充一些PURGE知識
Purge操作:
1). Purge tablespace tablespace_name : 用於清空表空間的Recycle Bin
2). Purge tablespace tablespace_name user user_name: 清空指定表空間的Recycle Bin中指定用戶的對象
3). Purge recyclebin: 刪除當前用戶的Recycle Bin中的對象
4). Purge dba_recyclebin: 刪除所有用戶的Recycle Bin中的對象,該命令要sysdba權限
5). Drop table table_name purge:  刪除對象並且不放在Recycle Bin中,即永久的刪除,不能用Flashback恢復。
6). Purge index recycle_bin_object_name: 當想釋放Recycle bin的空間,又想能恢復表時,可以通過釋放該對象的index所占用的空間來緩解空間壓力。 因為索引是可以重建的。
二、如果某些表占用了數據文件的最后一些塊,則需要先將該表導出或移動到其他的表空間中,然后刪除表,再進行收縮。不過如果是移動到其他的表空間,需要重建其索引。

1)SQL> alter table t_obj move tablespace t_tbs1;   ---移動表到其它表空間

也可以直接使用exp和imp來進行

2)SQL>alter owner.index_name rebuild;     --重建索引

3)刪除原來的表空間
三:對表分析之后也可以優化(本人沒有試過)

analyze table ysgl_compile_reqsub 
compute statistics for all indexes; 
也要看情況,不是什么情況都可以優化,等下次有機會再測試一下。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM