爲何delete後磁盤空間沒有釋放而truncate會釋放?

背景html

因項目需求,須要清理一批舊數據,騰出空間給新數據,讓同事負責這件事。料想會很順利,但很快找到我,並告知在postgresql中把一張大的數據表刪除掉了,查詢表的size並無改變。sql

爲何delete後磁盤空間沒有釋放而truncate會釋放?

 

我震驚了,問他怎麼刪除數據表的數據的,他告訴我使用"DELETE FROM table",而後使用下面的語句進行查詢數據庫

--數據庫中單個表的大小(不包含索引)
select pg_size_pretty(pg_relation_size('表名'));
--查出全部表(包含索引)並排序
SELECT table_schema || '.' || table_name AS table_full_name, pg_size_pretty(pg_total_relation_size('"' || table_schema || '"."' || table_name || '"')) AS size
FROM information_schema.tables
ORDER BY
pg_total_relation_size('"' || table_schema || '"."' || table_name || '"') DESC limit 20

我讓他用truncate試試,他興沖沖的跑去執行了,而後告訴我這個方法是可行的。post

解決方式測試

這件事情結束後,總以爲不踏實。不搞清楚,睡覺不踏實,那就繼續深挖挖。spa

delete應該沒有被真正刪除或者事務沒有完成,空間沒有釋放,從新測試了一遍,發現等了半個小時,空間也沒有釋放,應該不是事務的問題,就是沒有真正刪除,而僅僅標識爲已刪除狀態。日誌

想要釋放空間,怎麼辦呢?postgresql

postgresql提供了一個VACUUM命令,詳見https://www.postgresql.org/docs/devel/sql-vacuum.htmlcode

總結orm

  1. truncate的刪除效率遠遠高於delete from table
  2. Delete 是 DML, Truncate是DDL
  3. Delete 不釋放空間, Truncate釋放空間
  4. Delete 能夠刪除表的部分記錄, Truncate刪除整個表的記錄
  5. Delete產生小量的redo日誌和大量的undo日誌. Truncate產生的redo和undo微乎其微。

參考資料

【1】https://stackoverflow.com/questions/139630/whats-the-difference-between-truncate-and-delete-in-sql

相關文章
相關標籤/搜索