Eu estou tentando criar índices parciais para uma tabela estática grande (1.2TB) no Postgres 9.4.
Como meus dados são completamente estáticos, posso inserir todos os dados e criar todos os índices.
Nesta tabela de 1,2 TB, tenho uma coluna chamada run_id
que divide os dados de maneira limpa. Obtivemos um ótimo desempenho ao criar índices que cobrem uma variedade de run_id
s. Aqui está um exemplo:
CREATE INDEX perception_run_frame_idx_run_266_thru_270
ON run.perception
(run_id, frame)
WHERE run_id >= 266 AND run_id <= 270;
Esses índices parciais nos dão a velocidade de consulta desejada. Infelizmente, a criação de cada índice parcial leva cerca de 70 minutos.
Parece que estamos com CPU limitada ( top
está mostrando 100% para o processo).
Existe algo que eu possa fazer para acelerar a criação de nossos índices parciais?
Especificações do sistema:
- 18 core Xeon
- 192GB RAM
- 12 SSDs em RAID
- Os autovacuums estão desativados
- maintenance_work_mem: 64GB (Muito alto?)
Especificações da tabela:
- Tamanho: 1,26 TB
- Número de linhas: 10.537 bilhões
- Tamanho típico do índice: 3,2 GB (existe uma variação de ~ 0,5 GB)
Definição da tabela:
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))
(Não leia muito os nomes das colunas - eu os ofusquei um pouco.)
Informações de fundo:
- Temos uma equipe separada no local que consome esses dados, mas na verdade existem apenas um ou dois usuários. (Todos esses dados são gerados por meio de uma simulação.) Os usuários só começam a analisar os dados quando as inserções são concluídas e os índices são completamente construídos. Nossa principal preocupação é reduzir o tempo necessário para gerar dados utilizáveis e, no momento, o gargalo é o tempo de criação do índice.
- A velocidade da consulta foi completamente adequada ao usar parciais. Na verdade, acho que poderíamos aumentar o número de execuções que cada índice cobre e ainda manter um desempenho de consulta suficientemente bom.
- Meu palpite é que teremos que particionar a tabela. Estamos tentando esgotar todas as outras opções antes de seguir esse caminho.
completely static
, então o que você quer dizer com isso We have a separate team onsite that consumes this data
? Você apenas indexa o intervalo run_id >= 266 AND run_id <= 270
ou a tabela inteira? Qual é a expectativa de vida de cada índice / quantas consultas o usarão? Para quantos valores diferentes run_id
? Soa como ~ 15 milhões. linhas por run_id
, o que tornaria cerca de 800 valores diferentes para run_id
? Por que obj_type_set
, by_s_id
, seq
não definido NOT NULL? Qual porcentagem aproximada de valores NULL para cada um?
run_id
? Distribuído uniformemente? Tamanho do índice resultante no disco? Os dados são estáticos, ok. Mas você é o único usuário?