Как избежать фрагментарного хранения базы данных при очень частых обновлениях? - PullRequest
1 голос
/ 14 марта 2011

Когда у меня есть следующая таблица:

CREATE TABLE test
(
  "id" integer NOT NULL,
  "myval" text NOT NULL,
  CONSTRAINT "test-id-pkey" PRIMARY KEY ("id")
)

При выполнении большого количества запросов, таких как:

UPDATE "test" set "myval" = "myval" || 'foobar' where "id" = 12345

Тогда ряд myval будет становиться все больше и больше с течением времени. Что будет делать postgresql? Откуда он возьмет место?

Могу ли я избежать того, что postgresql нужно более одного запроса на чтение определенного myval-столбца?

Будет ли postgresql делать это автоматически?

Я знаю, что обычно я должен попытаться нормализовать данные намного больше. Но мне нужно прочитать значение одним поиском. Myval будет увеличиваться примерно на 20 байт с каждым обновлением (которое добавляет данные). Некоторые столбцы будут иметь 1-2 обновления, около 1000 обновлений. Обычно я бы просто использовал одну новую строку вместо обновления. Но тогда выбор становится медленным. Поэтому я пришел к мысли о денормализации.

Ответы [ 2 ]

4 голосов
/ 14 марта 2011

Измените FILLFACTOR таблицы, чтобы освободить место для будущих обновлений. Это также могут быть обновления HOT, потому что текстовое поле не имеет индекса, чтобы ускорить обновление и снизить затраты на автоочистку, потому что обновления HOT используют микровакуум. Оператор CREATE TABLE содержит некоторую информацию о FILLFACTOR .

ALTER TABLE test SET (fillfactor = 70);
-- do a table rebuild to blow some space in your current table:
VACUUM FULL ANALYZE test;
-- start testing

Значение 70 - не идеальная настройка, это зависит от вашей уникальной ситуации. Может быть, у вас все в порядке с 90, это также может быть 40 или что-то еще.

1 голос
/ 14 марта 2011

Это относится к этому вопросу о TEXT в PostgreSQL , или, по крайней мере, ответ аналогичен.PostgreSQL хранит большие столбцы вне основного хранилища таблиц:

Очень длинные значения также хранятся в фоновых таблицах, чтобы они не мешали быстрому доступу к более коротким значениям столбцов.

Таким образом, вы можете ожидать, что столбец TEXT (или BYTEA или большой VARCHAR) всегда будет храниться вдали от главной таблицы, и что-то вроде SELECT id, myval FROM test WHERE id = 12345 займет две попытки, чтобы вытащить обастолбцы с диска (и другие пытаются определить их местоположение).

Если ваши ОБНОВЛЕНИЯ действительно приводят к замедлению ваших SELECT, то, возможно, вам нужно пересмотреть свою стратегию вакуумирования .

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