Оптимизация PostgreSQL для переходных данных

8

У меня есть несколько таблиц с 100-300 столбцами целочисленных типов в каждой, которые содержат очень изменчивые данные. Наборы данных основываются на одном или двух первичных ключах, и когда происходит обновление, весь набор данных удаляется, и новые данные вставляются в одну транзакцию. Размер набора данных обычно составляет несколько сотен строк, но в крайних случаях может достигать нескольких тысяч строк. Обновление происходит один раз в секунду, и обновления набора данных для разных ключей обычно не связаны, поэтому удаление и повторное создание таблицы неосуществимо.

Как настроить Postgres для обработки такой нагрузки? Я могу использовать последнюю и лучшую версию, если это имеет какое-либо значение.

Алекс Токарев
источник

Ответы:

7

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

При обновлении набора данных, BEGINновой транзакции, TRUNCATEтаблицы, COPYновых данных в нем и COMMIT. PostgreSQL имеет оптимизацию где COPYать в таблицу , которая была TRUNCATEd в той же транзакции делает гораздо меньше I / O , если вы используете wal_level = minimal(по умолчанию).

Если вы не можете разделить и усечь (скажем, если вы имеете дело с десятками или сотнями тысяч наборов данных, где было бы слишком много таблиц), вы вместо этого захотите запустить автоочистку, чтобы запустить как можно больше. Убедитесь, что у вас есть хорошие индексы для всего, что вы удаляете на основе, и будьте готовы к несколько обычной производительности.

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

Если вы не возражаете против восстановления всей установки из резервной копии после сбоя системы, вы можете пойти еще дальше и также установить fsync=off, что в основном говорит PostgreSQL: «Не беспокойтесь о безопасности при сбое, у меня есть хорошие резервные копии, и я не Мне все равно, будут ли мои данные окончательно и полностью невосстановимыми после сбоя, и я рад повторно, initdbпрежде чем смогу снова использовать свою базу данных ".

Я написал еще об этом в аналогичной теме о переполнении стека об оптимизации PostgreSQL для быстрого тестирования ; в котором упоминается настройка ОС хоста, разделение WAL на другой диск, если вы не используете unloggedтаблицы, настройки контрольных точек и т. д.

В документации Pg также есть некоторая информация для быстрой загрузки данных и недолговременных настроек .

Крейг Рингер
источник
Спасибо за совет раздела, я никогда не думал об их использовании в этом случае. Что касается незарегистрированных таблиц - имеете ли вы в виду, что они заканчиваются пустыми по умолчанию после сбоя системы? Это не имеет никакого значения, мне просто любопытно.
Алексей Токарев,
1
@ AlexTokarev Это верно; после того, как PostgreSQL завершает работу нечисто (postmaster или back-end segfaults, внезапно происходят циклы включения системы, редактируется backend SIGKILLи т. д.), любые UNLOGGEDтаблицы могут быть TRUNCATEd, поэтому они пустые при запуске. Они не усекаются после полного выключения и перезапуска, но вы не должны полагаться на их долговечность.
Крейг Рингер
Спасибо за объяснение. Мне не нужна безопасность данных для рассматриваемых таблиц, данные в них являются временными и обновляются из источника каждую секунду. Отключение fsync - это не вариант, поскольку есть другие, более традиционные таблицы в той же схеме, которые должны быть безопасными и восстанавливаемыми. Наличие UNLOGGEDопции на стол просто замечательно.
Алексей Токарев
Я смотрю на документацию по разделам, и похоже, что это может быть (почти) идеальным решением проблемы. Хотя один вопрос: если я собираюсь иметь родительскую таблицу для схем и дочерних таблиц для хранения данных, я собираюсь запросить данные из родительской таблицы, верно? Если дочерняя таблица для этого диапазона существует, запрос вернет ее, если нет, то вернет пустой набор данных. В этом случае я могу даже удалить и заново создать дочерние таблицы для каждого нового пакета данных. Учитывая обстоятельства, что будет более эффективным, TRUNCATEили DROP/CREATE TABLEпоследовательность?
Алексей Токарев
@ AlexTokarev Я бы порекомендовал вам TRUNCATEлично. DDL маслобойка имеет свои расходы. Поскольку вы вносите изменения с такой высокой частотой, очень важно убедиться, что вы включили агрессивность автоочистки pg_catalog.pg_classи другие системные таблицы, которые могут раздуться под этой рабочей нагрузкой.
Крейг Рингер