一般來說mysql有三種刪除數據方式:
1. delete(常用)
2. truncate(慎用)
3. drop
以上三種方式都可以刪除數據,但是使用場景是不同的。
從執行速度來說:
drop > truncate >> DELETE
深入底層來說:
一、DELETE
DELETE是屬於數據庫的DML操作語言,使用delete刪除數據時,數據庫只能刪除數據不能刪除表的結構,會觸發數據庫的事務機制。
DELETE執行時,會先將所刪除數據緩存到rollback segement中,事務commit之后生效;
另外在mysql不同引擎下使用delete也是有一定區別的:
在InnoDB中,使用delete其實並不會真正的把數據刪除,是一種邏輯刪,數據庫底層實際上只是給刪除的數據做了一個已刪除的標記,因此,刪除數據后的表占空間大小和刪除前是一樣的,
執行delete操作的數據所占的空間,並不會被釋放,只是設置了不可見。雖然未釋放磁盤空間,但是這一部分的空間是依然可以重復使用的。(重用---》也是就覆蓋,新數據將有標記的數據覆蓋)
delete操作以后使用 optimize table table_name 會立刻釋放磁盤空間。不管是InnoDB還是MyISAM 。所以要想達到釋放磁盤空間的目的,delete以后執行optimize table 操作
對於帶有條件的刪除delete語句,執行后,在MyISAM和InnoDB下都不會釋放磁盤空間,想要立刻釋放空間,執行optimize table table_name即可。
查看表占磁盤大小SQL:(用M做展示單位)
SELECT
concat( round( sum( DATA_LENGTH / 1024 / 1024 ), 2 ), 'M' ) AS table_size
FROM
information_schema.TABLES
WHERE
table_schema = '庫'
AND table_name = '表'
優化表存儲大小SQL: optimize table 表名
delete 操作是一行一行執行刪除的,並且同時將該行的的刪除操作日志記錄在redo和undo表空間中以便進行回滾(rollback)和重做操作,生成的大量日志也會占用磁盤空間。
二、truncate
TRUNCATE刪除sql語句:Truncate table TABLE_NAME
1、truncate:屬於數據庫DDL定義語言,不走事務,原數據不放到 rollback segment 中,操作不觸發 trigger。(慎用刪除執行后,元數據就沒了,不可恢復)執行后立即生效,無法找回
2、truncate 刪除表會立刻釋放磁盤空間 ,不管是 InnoDB和MyISAM 。truncate table其實有點類似於drop table 然后creat,只不過這個create table 的過程做了優化,比如表結構文件之前已經有了等等。所以速度上應該是接近drop table的速度;
3、truncate能夠快速清空一個表。並且重置auto_increment的值。但對於不同的類型存儲引擎需要注意的地方是:
對於MyISAM,truncate會重置auto_increment(自增序列)的值為1。而delete后表仍然保持auto_increment。
對於InnoDB,truncate會重置auto_increment的值為1。delete后表仍然保持auto_increment。但是在做delete整個表之后重啟MySQL的話,則重啟后的auto_increment會被置為1。
也就是說,InnoDB的表本身是無法持久保存auto_increment。delete表之后auto_increment仍然保存在內存,但是重啟后就丟失了,只能從1開始。實質上重啟后的auto_increment會從 SELECT 1+MAX(ai_col) FROM t 開始。
三、drop
drop刪除表sql:Drop table Tablename
1、drop:屬於數據庫DDL定義語言,同Truncate;執行后立即生效,無法找回
2、drop table table_name 立刻釋放磁盤空間 ,不管是 InnoDB 和 MyISAM; drop 語句將刪除表的結構被依賴的約束(constrain)、觸發器(trigger)、索引(index); 依賴於該表的存儲過程/函數將保留,但是變為 invalid 狀態。