使用 DELETE 或 TRUNCATE 释放磁盘空间?

Has*_*aig 5 postgresql delete truncate

一个多星期前,我删除了 postgresql 表中的所有行(不是通过truncate,而是使用delete from ...)。Select count (*)显示表行现在为 0。

当我现在运行查询来查询磁盘空间时,我仍然看到该表占用了空间。具体来说,所有索引仍然存在并且正在占用空间。如何摆脱它们并释放磁盘空间?其次,当我摆脱了所有行时,为什么它们仍然留在首位?


以下是表格的详细说明,以防万一:

                                      Table "public.links_photoobjectsubscription"
     Column     |           Type           |                                 Modifiers                                  
----------------+--------------------------+----------------------------------------------------------------------------
 id             | integer                  | not null default nextval('links_photoobjectsubscription_id_seq'::regclass)
 viewer_id      | integer                  | not null
 updated_at     | timestamp with time zone | not null
 seen           | boolean                  | not null
 type_of_object | character varying(15)    | not null
 which_photo_id | integer                  | 
 which_link_id  | integer                  | 
 which_group_id | integer                  | 
 which_salat_id | integer                  | 
Indexes:
    "links_photoobjectsubscription_pkey" PRIMARY KEY, btree (id)
    "links_photoobjectsubscription_seen" btree (seen)
    "links_photoobjectsubscription_updated_at" btree (updated_at)
    "links_photoobjectsubscription_viewer_id" btree (viewer_id)
    "links_photoobjectsubscription_which_photo_id" btree (which_photo_id)
Foreign-key constraints:
    "links_photoobjectsubscription_viewer_id_fkey" FOREIGN KEY (viewer_id) REFERENCES auth_user(id) DEFERRABLE INITIALLY DEFERRED
    "links_photoobjectsubscription_which_photo_id_fkey" FOREIGN KEY (which_photo_id) REFERENCES links_photo(id) DEFERRABLE INITIALLY DEFERRED
    "which_group_id_photoobjectsubscription" FOREIGN KEY (which_group_id) REFERENCES links_group(id) ON DELETE CASCADE
    "which_link_id_photoobjectsubscription" FOREIGN KEY (which_link_id) REFERENCES links_link(id) ON DELETE CASCADE
    "which_salat_id_photoobjectsubscription" FOREIGN KEY (which_salat_id) REFERENCES links_salatinvite(id) ON DELETE CASCADE
Run Code Online (Sandbox Code Playgroud)

Eva*_*oll 9

从文档开始 VACUUM

VACUUM 有两种变体:标准 VACUUM 和 VACUUM FULL。VACUUM FULL 可以回收更多的磁盘空间,但运行速度要慢得多。此外,标准形式的 VACUUM 可以与生产数据库操作并行运行。(诸如 SELECT、INSERT、UPDATE 和 DELETE 之类的命令将继续正常运行,尽管在清理表时您将无法使用诸如 ALTER TABLE 之类的命令来修改表的定义。) VACUUM FULL 需要独占锁定它正在处理的表,因此不能与表的其他用途并行完成。因此,通常管理员应努力使用标准 VACUUM 并避免 VACUUM FULL。

您基本上需要发出一个命令来重写整个表(来自同一个文档),

提示:当由于大量更新或删除活动而导致表包含大量死行版本时,纯 VACUUM 可能无法令人满意。如果您有这样的表并且需要回收它占用的多余磁盘空间,则需要使用 VACUUM FULL,或者 CLUSTER 或 ALTER TABLE 的表重写变体之一。这些命令重写表的整个新副本并为其构建新索引。所有这些选项都需要排他锁。请注意,它们还会临时使用大约等于表大小的额外磁盘空间,因为表和索引的旧副本在新副本完成之前无法释放。

在同一份文件中,

提示:如果您有一个其整个内容定期删除的表,请考虑使用 TRUNCATE 来执行此操作,而不是使用 DELETE 后跟 VACUUM。TRUNCATE 立即删除表的全部内容,不需要后续的 VACUUM 或 VACUUM FULL 来回收现在未使用的磁盘空间。缺点是违反严格的 MVCC 语义

而且,从文档开始 TRUNCATE

TRUNCATE 从一组表中快速删除所有行。它与对每个表的非限定 DELETE 具有相同的效果,但由于它实际上并不扫描表,因此速度更快。此外,它会立即回收磁盘空间,而不需要后续的 VACUUM 操作。这在大表上最有用。