Я пытаюсь создать частичные индексы для большой (1,2 ТБ) статической таблицы в Postgres 9.4.
Мои данные полностью статичны, поэтому я могу вставить все данные, а затем создать все индексы.
В этой таблице размером 1,2 ТБ у меня есть столбец, run_id
который четко разделяет данные. Мы добились отличной производительности, создав индексы, которые охватывают диапазон run_id
s. Вот пример:
CREATE INDEX perception_run_frame_idx_run_266_thru_270
ON run.perception
(run_id, frame)
WHERE run_id >= 266 AND run_id <= 270;
Эти частичные индексы дают нам желаемую скорость запроса. К сожалению, создание каждого частичного индекса занимает около 70 минут.
Похоже, мы ограничены процессором ( top
показывает 100% для процесса).
Что я могу сделать, чтобы ускорить создание наших частичных индексов?
Системные характеристики:
- 18 ядро Xeon
- ОЗУ 192 ГБ
- 12 SSD в RAID
- Автовакуум выключен
- maintenance_work_mem: 64 ГБ (слишком высоко?)
Таблица спецификаций:
- Размер: 1,26 ТБ
- Количество рядов: 10,537 млрд
- Типичный размер индекса: 3,2 ГБ (разница составляет ~. 5 ГБ)
Определение таблицы:
CREATE TABLE run.perception(
id bigint NOT NULL,
run_id bigint NOT NULL,
frame bigint NOT NULL,
by character varying(45) NOT NULL,
by_anyone bigint NOT NULL,
by_me bigint NOT NULL,
by_s_id integer,
owning_p_id bigint NOT NULL,
obj_type_set bigint,
seq integer,
subj_id bigint NOT NULL,
subj_state_frame bigint NOT NULL,
CONSTRAINT perception_pkey PRIMARY KEY (id))
(Не читайте слишком много имен столбцов - я их немного запутал.)
Справочная информация:
- У нас есть отдельная команда, которая использует эти данные, но на самом деле есть только один или два пользователя. (Все эти данные генерируются с помощью симуляции.) Пользователи начинают анализировать данные только после того, как вставки завершены и индексы полностью построены. Наша главная задача - сократить время, необходимое для генерации полезных данных, и сейчас узким местом является время создания индекса.
- Скорость запросов была полностью адекватной при использовании партиалов. На самом деле, я думаю, что мы могли бы увеличить количество прогонов, охватываемых каждым индексом, и при этом поддерживать достаточную производительность запросов.
- Я предполагаю, что нам придется разделить таблицу. Мы пытаемся исчерпать все другие варианты, прежде чем идти по этому маршруту.
completely static
, то что вы имеете в виду We have a separate team onsite that consumes this data
? Вы просто индексируете диапазон run_id >= 266 AND run_id <= 270
или всю таблицу? Какова продолжительность жизни каждого индекса / сколько запросов будет его использовать? Сколько разных значений для run_id
? Звучит как ~ 15 млн. строк за run_id
, что сделает около 800 различных значений для run_id
? Почему obj_type_set
, by_s_id
, seq
не определены как NOT NULL? Какой приблизительный процент значений NULL для каждого?
run_id
? Равномерно распределены? Размер результирующего индекса на диске? Данные статичны, хорошо. Но ты единственный пользователь?