postgresql - 估计 PostgreSQL 中删除列的影响大小
问题描述
我在 PostgreSQL 中有一个表,其中两列包含图像作为文本(不是我的决定..)。所以,现在我不需要这些列,我打算删除它们。但是当我想估计删除列的“效果”时,我遇到了一个问题,即表的大小会改变多少。问题是 PostgreSQL 显示新旧表的大小相同。这很奇怪,因为我要删除两个“重”列。
下面是比较代码:
-- Create two copies of the table
CREATE TABLE oldwords (LIKE "words" INCLUDING INDEXES);
INSERT INTO oldwords SELECT * FROM "words";
CREATE TABLE newwords (LIKE "words" INCLUDING INDEXES);
INSERT INTO newwords SELECT * FROM "words";
-- Drop columns containing images
ALTER TABLE "newwords"
DROP COLUMN image_black,
DROP COLUMN image_colored;
-- Update stats of the tables
VACUUM ANALYZE "oldwords";
VACUUM ANALYZE "newwords";
-- Compare size
SELECT
relname as "Table",
pg_size_pretty(pg_total_relation_size(relid)) As "Size",
pg_size_pretty(pg_total_relation_size(relid) -
pg_relation_size(relid)) as "External Size"
FROM pg_catalog.pg_statio_user_tables
WHERE relname LIKE '___words'
ORDER BY pg_total_relation_size(relid) DESC
-- RESULT
Table Size External Size
newwords 296 MB 205 MB
oldwords 296 MB 205 MB
难道我做错了什么?为什么尺寸一样?正确的方法是什么?
解决方案
来自ALTER TABLE
:
DROP COLUMN 表单不会物理删除列,只是使其对 SQL 操作不可见。表中的后续插入和更新操作将存储该列的空值。
因此,删除列很快,但不会立即减少表的磁盘大小,因为被删除列占用的空间不会被回收。随着现有行的更新,空间将随着时间的推移而被回收。(这些语句在删除系统 oid 列时不适用;这是通过立即重写来完成的。)
要强制立即回收被删除的列占用的空间,您可以执行 ALTER TABLE 的一种形式,该形式执行整个表的重写。这将导致重建每一行,并将删除的列替换为空值。
推荐阅读
- solidity - 使用上传到 github 的外部文件创建可更新的 bsc 合同
- php - 超过一定大小的 jQuery/PHP 上传失败,但仅适用于某些用户
- azure - 在本地 Kubernetes 上挂载 Azure 文件共享(Docker 桌面 Mac)
- aws-lambda - 访问触发放大功能的域或域名
- python - 在python中返回带有列的数据框
- python - TypeError:“BlockManager”对象不可迭代
- autodesk-forge - 在 Autodesk Forge Viewer 中查看时,镜像模型的材质会由内向外翻转
- database - 使用 HikariCP 处理数据库实例自动缩放的最佳方法?
- database - 如何让docker等待/docker-entrypoint-initdb.d中的SQL脚本被执行
- wordpress - 保存在 wordpress 页面上访问的最后一个位置