Estoy tratando de crear índices parciales para una tabla estática grande (1.2TB) en Postgres 9.4.
Mis datos son completamente estáticos, por lo que puedo insertar todos los datos y luego crear todos los índices.
En esta tabla de 1.2TB, tengo una columna llamada run_id
que divide limpiamente los datos. Hemos obtenido un gran rendimiento al crear índices que cubren un rango de run_id
s. Aquí hay un ejemplo:
CREATE INDEX perception_run_frame_idx_run_266_thru_270
ON run.perception
(run_id, frame)
WHERE run_id >= 266 AND run_id <= 270;
Estos índices parciales nos dan la velocidad de consulta deseada. Desafortunadamente, la creación de cada índice parcial lleva unos 70 minutos.
Parece que estamos limitados por la CPU ( top
se muestra 100% para el proceso).
¿Hay algo que pueda hacer para acelerar la creación de nuestros índices parciales?
Especificaciones del sistema:
- 18 núcleos Xeon
- 192 GB de RAM
- 12 SSD en RAID
- Las aspiradoras automáticas están apagadas
- maintenance_work_mem: 64GB (¿Demasiado alto?)
Especificaciones de la mesa:
- Tamaño: 1,26 TB
- Número de filas: 10.537 mil millones
- Tamaño de índice típico: 3.2 GB (hay una variación de ~ .5 GB)
Definición de tabla:
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))
(No lea demasiado los nombres de las columnas, los he ofuscado un poco).
Información de fondo:
- Tenemos un equipo separado en el sitio que consume estos datos, pero en realidad solo hay uno o dos usuarios. (Todos estos datos se generan a través de una simulación). Los usuarios solo comienzan a analizar los datos una vez que las inserciones están terminadas y los índices están completamente integrados. Nuestra principal preocupación es reducir el tiempo requerido para generar datos utilizables, y en este momento el cuello de botella es el tiempo de creación del índice.
- La velocidad de consulta ha sido completamente adecuada cuando se usan parciales. De hecho, creo que podríamos aumentar el número de ejecuciones que cubre cada índice y aún así mantener un rendimiento de consulta lo suficientemente bueno.
- Supongo que tendremos que dividir la tabla. Estamos tratando de agotar todas las demás opciones antes de tomar esa ruta.
completely static
, entonces, ¿qué quiere decir con We have a separate team onsite that consumes this data
? ¿Acabas de indexar el rango run_id >= 266 AND run_id <= 270
o toda la tabla? ¿Cuál es la esperanza de vida de cada índice / cuántas consultas lo usarán? ¿Para cuántos valores diferentes run_id
? Suena como ~ 15 millones. filas por run_id
, ¿cuál sería alrededor de 800 valores diferentes para run_id
? ¿Por qué son obj_type_set
, by_s_id
, seq
no definido NO NULO? ¿Qué porcentaje aproximado de valores NULL para cada uno?
run_id
? ¿Distribuidos equitativamente? Tamaño del índice resultante en el disco? Los datos son estáticos, ok. ¿Pero eres el único usuario?