Sto cercando di creare indici parziali per una tabella statica di grandi dimensioni (1,2 TB) in Postgres 9.4.
I miei dati sono completamente statici, quindi sono in grado di inserire tutti i dati, quindi creare tutti gli indici.
In questa tabella da 1,2 TB, ho una colonna denominata run_id
che divide in modo pulito i dati. Abbiamo ottenuto grandi prestazioni creando indici che coprono una gamma di run_id
s. Ecco un esempio:
CREATE INDEX perception_run_frame_idx_run_266_thru_270
ON run.perception
(run_id, frame)
WHERE run_id >= 266 AND run_id <= 270;
Questi indici parziali ci forniscono la velocità di query desiderata. Sfortunatamente, la creazione di ciascun indice parziale richiede circa 70 minuti.
Sembra che siamo limitati alla CPU ( top
sta mostrando il 100% per il processo).
C'è qualcosa che posso fare per accelerare la creazione dei nostri indici parziali?
Specifiche di sistema:
- 18 core Xeon
- 192 GB di RAM
- 12 SSD in RAID
- Gli autovuoti sono disattivati
- maintenance_work_mem: 64 GB (troppo alto?)
Specifiche della tabella:
- Dimensioni: 1,26 TB
- Numero di file: 10.537 miliardi
- Dimensione tipica dell'indice: 3,2 GB (esiste una variazione di ~ 0,5 GB)
Definizione della tabella:
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))
(Non leggere troppo nei nomi delle colonne - li ho offuscati un po '.)
Informazioni sullo sfondo:
- Abbiamo un team separato in loco che consuma questi dati, ma in realtà ci sono solo uno o due utenti. (Tutti questi dati vengono generati tramite una simulazione.) Gli utenti iniziano ad analizzare i dati solo dopo aver terminato gli inserti e aver creato gli indici. La nostra principale preoccupazione è ridurre il tempo necessario per generare dati utilizzabili e in questo momento il collo di bottiglia è il tempo di creazione dell'indice.
- La velocità della query è stata completamente adeguata durante l'utilizzo dei parziali. In effetti, penso che potremmo aumentare il numero di esecuzioni coperte da ciascun indice e mantenere comunque prestazioni di query sufficientemente buone.
- La mia ipotesi è che dovremo partizionare la tabella. Stiamo cercando di esaurire tutte le altre opzioni prima di intraprendere questa strada.
completely static
, allora cosa intendi We have a separate team onsite that consumes this data
? Indicizzi solo l'intervallo run_id >= 266 AND run_id <= 270
o l'intera tabella? Qual è l'aspettativa di vita di ciascun indice / quante query lo utilizzeranno? Quanti valori diversi per run_id
? Suona come ~ 15 Mio. righe per run_id
, che renderebbe circa 800 valori diversi per run_id
? Perché sono obj_type_set
, by_s_id
, seq
non definita NOT NULL? Quale percentuale approssimativa di valori NULL per ciascuno?
run_id
? Uniformemente distribuito? Dimensione dell'indice risultante sul disco? I dati sono statici, ok. Ma sei l'unico utente?