為什么delete后磁盤空間沒有釋放而truncate會釋放?


背景

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

為什么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試試,他興沖沖的跑去執行了,然后告訴我這個方法是可行的。

解決方式

這件事情結束后,總覺得不踏實。不搞清楚,睡覺不踏實,那就繼續深挖挖。

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

想要釋放空間,怎么辦呢?

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

總結

  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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM