代码之家  ›  专栏  ›  技术社区  ›  Niro

Postgres将列从TEXT更改为INTEGER会增加表的大小

  •  1
  • Niro  · 技术社区  · 6 年前

    我有一个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)
    

                                                      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字节整数而不是文本。其实,这两个表的行数是一样的。产品表(带整型字段的表)的大小为34.3 GB。而旧表的大小(包含文本)为19.7GB

    2 回复  |  直到 6 年前
        1
  •  0
  •   Richard Huxton    6 年前

    大概您已经使用各种altertable命令完成了这项工作,这些命令至少强制重写整个表一次。

    未使用的空间将逐渐重新使用,或尝试进行更迅速的更改 CLUSTER VACUUM FULL 在桌子上。

        2
  •  0
  •   Alex    6 年前

    VACUUM 命令。

    数据库文件是元组的有组织的集合。一行可以由一个或多个元组组成。添加新列时,向表文件中添加了元组。但是删除列时,元组占用的空间仍然存在,因为从文件中删除它是一项代价高昂的操作。它们是死元组。

     VACUUM FULL am.product;