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_reqsubcompute statistics for all indexes;
也要看情況,不是什麼情況都可以優化,等下次有機會再測試一下。
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...
oracle 刪除表中重覆記錄
表demo是重複拷貝自dba objects,有88萬左右,不重複的是27323,沒有索引 方法一 delete from demo a where a.rowid select max rowid from demo b where b.object id a.object id 耗時 幾個小時以...
如何刪除表中重複的記錄?
由於多種原因,在表中可能會有一些重複的記錄,有時需要刪除這些重複的記錄,那麼,如何刪除這些重複的記錄呢?現有如下的表 sql create table a 2 b number 1 表已建立。sql insert into a values 1 已建立 1 行。sql 已建立 1 行。sql 已建立...