我有一个postgres表,它具有这样的模式
Table "am.old_product"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
-----------------+--------------------------+-----------+----------+---------+----------+--------------+-------------
p_config_sku | text | | | | extended | |
p_simple_sku | text | | | | extended | |
p_merchant_id | text | | | | extended | |
p_country | character varying(2) | | | | extended | |
p_discount_rate | numeric(10,2) | | | | main | |
p_black_price | numeric(10,2) | | | | main | |
p_red_price | numeric(10,2) | | | | main | |
p_received_at | timestamp with time zone | | | | plain | |
p_event_id | uuid | | | | plain | |
p_is_deleted | boolean | | | | plain | |
Indexes:
"product_p_simple_sku_p_country_p_merchant_id_idx" UNIQUE, btree (p_simple_sku, p_country, p_merchant_id)
"config_sku_country_idx" btree (p_config_sku, p_country)
我们认为,删除TEXT字段mercant_id并将其移动到另一个表,并使用外键在产品表中引用它是一个更好的主意。因此,新架构看起来像这样。
Table "am.product"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
-------------------+--------------------------+-----------+----------+---------+----------+--------------+-------------
p_config_sku | text | | not null | | extended | |
p_simple_sku | text | | not null | | extended | |
p_country | character varying(2) | | not null | | extended | |
p_discount_rate | numeric(10,2) | | | | main | |
p_black_price | numeric(10,2) | | | | main | |
p_red_price | numeric(10,2) | | | | main | |
p_received_at | timestamp with time zone | | not null | | plain | |
p_event_id | uuid | | not null | | plain | |
p_is_deleted | boolean | | | false | plain | |
p_merchant_id_new | integer | | not null | | plain | |
Indexes:
"new_product_p_simple_sku_p_country_p_merchant_id_new_idx" UNIQUE, btree (p_simple_sku, p_country, p_merchant_id_new)
"p_config_sku_country_idx" btree (p_config_sku, p_country)
Foreign-key constraints:
"fk_merchant_id" FOREIGN KEY (p_merchant_id_new) REFERENCES am.merchant(m_id)
现在,这应该使产品表的尺寸正确吗?我们使用的是4个字节的整数,而不是TEXT。事实并非如此,两个表具有相同的确切行数。产品表(带有一个整数字段)的大小为34.3 GB。旧表的大小(带有TEXT)为19.7GB
有人对此有解释吗?
答案 0 :(得分:0)
您可以通过各种ALTER TABLE命令强制执行至少一次重写整个表的操作。
未使用的空间将逐渐重新使用,或者为了更迅速地进行更改,请尝试在表上使用CLUSTER
或VACUUM FULL
。
答案 1 :(得分:0)
查看VACUUM命令。
数据库文件是元组的有组织的集合。一行可以由一个或多个元组组成。添加新列时,将元组添加到表文件中。但是,当您删除一列时,元组会占用空间,因为从文件中删除它是一项昂贵的操作。他们是死元组。
VACUUM FULL am.product;
不幸的是,这将在表上创建排他锁,您将无法在该过程中查询它。