J'essaie de créer des index partiels pour une grande table statique (1,2 To) dans Postgres 9.4.
Mes données sont complètement statiques, je peux donc insérer toutes les données, puis créer tous les index.
Dans ce tableau de 1,2 To, j'ai une colonne nommée run_id
qui divise proprement les données. Nous avons obtenu d'excellentes performances en créant des index qui couvrent une gamme de run_id
s. Voici un exemple:
CREATE INDEX perception_run_frame_idx_run_266_thru_270
ON run.perception
(run_id, frame)
WHERE run_id >= 266 AND run_id <= 270;
Ces index partiels nous donnent la vitesse de requête souhaitée. Malheureusement, la création de chaque index partiel prend environ 70 minutes.
Il semble que nous ayons un processeur limité ( top
affiche 100% pour le processus).
Puis-je faire quelque chose pour accélérer la création de nos index partiels?
Spécifications du système:
- Xeon 18 cœurs
- 192 Go de RAM
- 12 SSD en RAID
- Les autovacuums sont désactivés
- maintenance_work_mem: 64 Go (Trop haut?)
Spécifications du tableau:
- Taille: 1,26 To
- Nombre de lignes: 10,537 milliards
- Taille d'index typique: 3,2 Go (il existe une variance de ~ 0,5 Go)
Définition du tableau:
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))
(Ne lisez pas trop les noms des colonnes - je les ai quelque peu obscurcis.)
Informations de fond:
- Nous avons une équipe distincte sur place qui consomme ces données, mais il n'y a vraiment qu'un ou deux utilisateurs. (Ces données sont toutes générées via une simulation.) Les utilisateurs ne commencent à analyser les données qu'une fois les insertions terminées et les index entièrement construits. Notre principale préoccupation est de réduire le temps nécessaire pour générer des données utilisables, et actuellement le goulot d'étranglement est le temps de création d'index.
- La vitesse de requête a été tout à fait adéquate lors de l'utilisation de partiels. En fait, je pense que nous pourrions augmenter le nombre d'exécutions couvertes par chaque index, tout en maintenant des performances de requête suffisamment bonnes.
- Je suppose que nous devrons partitionner la table. Nous essayons d'épuiser toutes les autres options avant d'emprunter cette voie.
completely static
, que voulez-vous dire par là We have a separate team onsite that consumes this data
? Indexez-vous simplement la plage run_id >= 266 AND run_id <= 270
ou la table entière? Quelle est l'espérance de vie de chaque index / combien de requêtes l'utiliseront? Pour combien de valeurs différentes run_id
? Sonne comme ~ 15 Mio. lignes par run_id
, ce qui ferait environ 800 valeurs différentes pour run_id
? Pourquoi sont obj_type_set
, by_s_id
, seq
non défini NOT NULL? Quel pourcentage approximatif des valeurs NULL pour chacun?
run_id
? Distribué équitablement? Taille de l'index résultant sur le disque? Les données sont statiques, ok. Mais êtes-vous le seul utilisateur?