Oracle資料庫表是否需要磁碟重組
近日有mysql的朋友問我 Oracle資料庫的表是否需要定期進行磁碟重組,由於Oracle的資料表的儲存。不像mysql(innodb)那樣使用的聚集組織表(IOT)存放資料,而是使用的是稱為堆(HEAP)的方式來存放資料。資料行被存放到的塊是隨機的.進行全表掃描的時候讀取出來的資料行沒有按一定的方式進行排序.所以Oracle可以對任意有空閑空間的資料區塊進行資料插入。
假設我們現在建立一個表,過程如下.
SQL> create table t2 as select * from dba_objects;
Table created.
SQL> exec dbms_stats.gather_table_stats('SYS','T2');
PL/SQL procedure successfully completed.
得到當前的表的資料區塊,行資訊
SQL> select table_name,num_rows,blocks,num_rows/blocks from dba_tables where table_name='T2' and owner='SYS';
TABLE_NAME NUM_ROWS BLOCKS NUM_ROWS/BLOCKS
------------------------------ ---------- ---------- ---------------
T2 90426 1535 59.9094463
當前該表擁有90426行,1535個資料區塊,平均每個塊大概是存放了59行資料.
我們通過如下的PLSQL代碼來摸擬隨機刪除10000條資料;
SQL> declare
i number;
begin
for i in 1..10000 loop
delete from t2 where object_id=round(dbms_random.value(0,90000));
end loop;
commit;
end;
PL/SQL procedure successfully completed.
SQL> exec dbms_stats.gather_table_stats('SYS','T2');
PL/SQL procedure successfully completed.
SQL> select table_name,num_rows,blocks,num_rows/blocks from dba_tables where table_name='T2' and owner='SYS';
TABLE_NAME NUM_ROWS BLOCKS NUM_ROWS/BLOCKS
------------------------------ ---------- ---------- ---------------
T2 81413 1535 53.037785
刪除10000行後,表的資料區塊不發生變化,但是平均每個塊是存放53行資料.
現在摸擬隨機插入資料
SQL> declare
i number;
begin
for i in 1..10000 loop
insert into t2(OWNER, OBJECT_NAME, SUBOBJECT_NAME, OBJECT_ID, DATA_OBJECT_ID, OBJECT_TYPE, CREATED, LAST_DDL_TIME, TIMESTAMP, STATUS, TEMPORARY,
GENERATED, SECONDARY, NAMESPACE, EDITION_NAME, SHARING, EDITIONABLE, ORACLE_MAINTAINED)
values ('SYS', 'I_COBJ#', null, 30, 30, 'INDEX', to_date('07-07-2014 05:39:01', 'dd-mm-yyyy hh24:mi:ss'), to_date('07-07-2014 05:39:01', 'dd-mm-yyyy
hh24:mi:ss'), '2014-07-07:05:39:01', 'VALID', 'N', 'N', 'N', 4, null, 'NONE', null, 'Y');
end loop;
commit;
end;
PL/SQL procedure successfully completed.
SQL> exec dbms_stats.gather_table_stats('SYS','T2');
PL/SQL procedure successfully completed.
SQL> select table_name,num_rows,blocks,num_rows/blocks from dba_tables where table_name='T2' and owner='SYS';
TABLE_NAME NUM_ROWS BLOCKS NUM_ROWS/BLOCKS
------------------------------ ---------- ---------- ---------------
T2 91413 1535 59.552443
我們看到Oracle並沒有為這個表新分配資料區塊,還是使用原來的資料區塊的空閑空間.當某些塊中原來的部分資料行被刪除時,這一部分空間可以被重用,這也是為什麼oracle的表不需要進行磁碟重組的原因。