先來從整體上看這三者:delete是屬於dml,truncate和drop是ddl;在刪除操作上,delete只是會刪除數據,而且是要生成日誌文件的,並且可以通過rollback回滾數據;但truncate和drop則會刪除所在的表的結構與空間,而且不可回滾;下面從Oracle的輸出日誌文檔來看看這些操作(以下操作均在sqlplus中進行)。
1.數據準備,創建一個表
create table t_part(object_id int,object_name varchar2(1000))
partition by range(object_id)(
partition p1 values less than(10000),
partition p2 values less than(20000),
partition p3 values less than(30000),
partition p4 values less than(40000),
partition pm values less than(maxvalue)
);
insert into t_part select object_id,object_name from sys.dba_objects;
查看總體數據量: select count(*) from t_part; 72561
查看分區的數據量:select count(*) from t_part partition(p1); 9708
select count(*) from t_part partition(p2); 9978;
select count(*) from t_part partition(p1); 10000;
2.開始刪除並比較,這裏先進行追蹤顯示:
2.1修改會話追蹤 : alter session set sql_trace=true;
2.2分別進行刪除操作:
delete from t_part where object_id<9708;
alter table t_part drop partition p2;
alter table t_part truncate partition p3;
2.3關閉會話追蹤。
因爲打開了會話追蹤,以上的操作都會生成一個輸出文檔在默認的路徑,在sqlplus中輸入 show parameter user_dump_dest;
2.4 退出sqlplus切換到該目錄下,在這裏使用tkprof工具將次文件整理並重定向到d盤中
切換到該目錄下找到該文件
然後在cmd中切換到該目錄下輸入:tkprof 追蹤文件名 重定向的文件路徑
然後找到該文件打開,會發現裏面有很多東西,
中間的那幾個參數說明要注意;
COUNT:這個語句被parse、execute、fetch的次數
CPU:cpu被佔用的時間
ELAPSED: 這個語句所有消耗在parse、execute、fetch的總的時間
DISK: 從磁盤上的數據文件中物理讀取的塊的數量。一般來說更想知道的是正在從緩存 中讀取的數據而不是從磁盤上讀取的數據
QUERY: 在一致性讀模式下,所有parse、execute、fetch所獲得的buffer的數量。 一致性模式的buffer是用於給一個長時間運行的事務提供一個一致性讀的快照,緩存實際上在頭部存儲了狀態。
CURRENT: 在current模式下所獲得的buffer的數量。一般在current模式下執行insert、update、delete操作都會獲取buffer。在current模式下如果在高速緩存區發現有新的緩存足夠給當前的事務使用,則這些buffer都會被讀入了緩存區中。
ROWS: 所有SQL語句返回的記錄數目,但是不包括子查詢中返回的記錄數目。對於select語句,返回記錄是在fetch這步,對於insert、update、delete操作,返回記錄則是在execute這步。
接下來找到我們操作的那幾句sql
delete語句:
drop 語句:
truncate 語句:
對比圖中的數據可以看出,drop與truncate不去操作某一行,就不用進行全表掃描(當然這裏沒有加入索引),所以操作的過程就更會簡單尤其是在 QUERY和CURRENT的處理上消耗明顯要小,在數據越大的情況下這種差別越明顯。一般來講在速度上drop>truncate>delete.
3.再來刪除數據之後表所佔的空間
新建表:create table t as select object_id,object_name from sys.dba_objects;
查出表空間的大小:select count(*) from user_extents wher segment_name='T'(這裏的表名要大寫,因爲Oracle會在沒有引號的情況下將所的語句轉爲大寫,但是有引號就會保持引號的內容,在創建表的時候,存在數據庫裏面的表名是T);
delete t;
同樣再查詢一次發現表空間沒有變,而使用drop和truncate就會明顯看出縮小了。
實際上delete之後還可以用下面的語句:alter table t move;這個的作用就相當於磁盤碎片整理,會對錶的空間重新進行分配,也會大大減少空表所佔的空間