Postgres Изменение столбца с TEXT на INTEGER увеличивает размер таблицы - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть таблица 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 merchant_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-байтовое целое число вместо текста. Ну, не совсем, две таблицы имеют одинаковое количество строк. Размер таблицы продуктов (один с целочисленным полем) составляет 34,3 ГБ. В то время как старый размер таблицы (с ТЕКСТОМ) имеет размер 19,7 ГБ

У кого-нибудь есть объяснение этому?

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Посмотрите на команду VACUUM .

Файл базы данных - это организованная коллекция кортежей. Строка может состоять из одного или нескольких кортежей. Когда вы добавили новый столбец, вы добавили кортежи в файл таблицы. Но когда вы отбрасываете столбец, пространство, занимаемое кортежами, остается, потому что удаление его из файла является дорогостоящей операцией. Это мертвые кортежи.

 VACUUM FULL am.product;

К сожалению, это создаст эксклюзивные блокировки для таблицы, и вы не сможете запросить ее в процессе.

0 голосов
/ 06 ноября 2018

По дикой догадке, вы сделали это с помощью различных команд ALTER TABLE, форсирующих хотя бы одно переписывание всей таблицы.

Неиспользуемое пространство будет постепенно использоваться повторно, или для более быстрого изменения попробуйте CLUSTER или VACUUM FULL на столе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...