Какой фактор заполнения для кэширования таблицы?

10

Я сильно обновил / получил доступ к таблице, где я храню сериализованные объекты Java. Они находятся в таблице в течение 2-3 часов (также обновляются в течение этого периода), а затем удаляются. Размер таблицы составляет около 300 МБ. Я заметил, что это очень, очень часто ВАКУУМНО и интересно fillfactor, поможет ли изменение ?

Michal
источник

Ответы:

17

Ключевые слова здесь:

  1. "сильно обновлено"
  2. «в таблице 2-3 часа».

Точка 1. указывает на более низкий коэффициент заполнения, а 2. - наоборот. Это повышает производительность, если несколько версий строк хранятся на одной странице данных. Горячие обновления достигнут этого. Читайте здесь или здесь . Им требуется некоторое пространство для маневра на странице данных - например, мертвые кортежи или пространство, зарезервированное fillfactor<100. Но они могут делать свое дело, только если в индексе нет ни одного из обновленных столбцов , что должно быть верно для вашего случая.

Другим важным фактором здесь будет размер кортежа (по сравнению с размером вашей страницы (который обычно составляет 8 КБ). Подробнее в этом связанном ответе:

Если размер кортежа составляет 4 КБ или более, уменьшение коэффициента заполнения будет бесполезным, поскольку на странице данных никогда не может быть более одного кортежа. С таким же успехом вы можете оставить его в 100(это значение по умолчанию в любом случае). Однако некоторые типы данных «всплывают» и сохраняются вне строки, если они превышают ограничение размера, поэтому кортежи, требующие такого большого количества в форке основного отношения, встречаются редко.

Что бы вы ни делали, VACUUM будет часто запускаться. И это вообще хорошо, я бы об этом не беспокоился. Вы создаете много мертвых кортежей. VACUUMопределяет мертвые строки, которые больше не видны ни одной открытой транзакции. Руководство:

Стандартная форма VACUUMудаляет мертвые версии строк в таблицах и индексах и отмечает пространство, доступное для повторного использования в будущем .

Жирный акцент мой.
Вы можете поиграть с настройками для каждой таблицы для автоматического вакуума, чтобы активировать его реже (или чаще) только для этой таблицы:

Пороговые значения по умолчанию и масштабные коэффициенты взяты из postgresql.conf, но их можно переопределить для каждой таблицы ;

Жирный акцент мой. В частности с autovacuum_vacuum_thresholdиautovacuum_vacuum_scale_factor . Запуск VACUUMмного может быть на самом деле хорошая идея, а очень низкий fillfacter. Это зависит от моделей доступа. Если все кортежи живут, скажем, 3 часа и каждый обновляется несколько раз, я бы все равно уменьшил их fillfactorдо 50. Вам нужно будет проверить и найти подходящее место.

альтернативы

Все это в стороне, поскольку ваши данные кажутся нестабильными для начала: используйте UNLOGGEDтаблицу :

Данные, записанные в незагруженные таблицы, не записываются в журнал предварительной записи (см. Главу 29 ), что делает их значительно быстрее, чем обычные таблицы. Тем не менее, они не защищены от сбоев : незагрязненная таблица автоматически обрезается после сбоя или нечистого завершения работы. Содержимое незарегистрированной таблицы также не реплицируется на резервные серверы.

Жирный акцент мой. Не используйте это, если ваш сервер может произойти сбой, и вам все еще нужны данные впоследствии. Но если мы говорим о данных сеанса для веб-приложений, это может быть приемлемой ценой.

Или, что еще более радикально: используйте хранилище значений ключей, такое как Redis, если вы можете вообще обходиться без функций и безопасности, обеспечиваемых СУБД.

Эрвин Брандштеттер
источник
Я думаю, что UNLOGGED это именно то, что мне нужно
Михал
0

Я бы предложил СУБД с ключом-значением, но я выкидываю это ради интереса.

Вместо выполнения операторов INSERT & DELETE, выполняйте только ОБНОВЛЕНИЯ.

Структура таблицы будет примерно такой

ID      integer  -- sequential ID
Used    boolean  -- default FALSE
Object  -- whatever type is appropriate

Столбец для хранения объектов будет иметь фиксированную длину, чтобы избежать разбиений и перемещения строк. Размер этого столбца, чтобы разместить ваши объекты и эффективно заполнить страницу на диске.

Предварительно заполните таблицу столько строк, сколько вам нужно, и еще несколько.

Когда объект должен быть написан, найдите строку с Used = False и ОБНОВИТЕ эту строку. Когда объект должен быть уничтожен, установите для него значение «Ложь». Там нет созданного мусора и, следовательно, нет сборки мусора.

Конечно, есть много, много исключительных условий для обработки (переполнение строки, переполнение таблицы, условия гонки при использовании идентификатора и т. Д.), Но ни одно из них не является непреодолимым.

Майкл Грин
источник
Насколько я понимаю, эти ОБНОВЛЕНИЯ обычно все еще записывают новую копию строки на диск, если это не ГОРЯЧЕЕ обновление. Таким образом, вам все равно понадобится GC / Vacuuming с течением времени.
Джефф Видман