J'ai une table avec beaucoup d'insertions, définissant l'un des champs ( uploaded_at
) sur NULL
. Une tâche périodique sélectionne ensuite tous les tuples WHERE uploaded_at IS NULL
, les traite et les met à jour, en définissant uploaded_at
la date actuelle.
Comment dois-je indexer la table?
Je comprends que je devrais utiliser un index partiel comme:
CREATE INDEX foo ON table (uploaded_at) WHERE uploaded_at IS NULL
Ou quelque chose comme ça. Je suis un peu confus cependant s'il est correct d'indexer sur un champ qui l'est toujours NULL
. Ou s'il est correct d'utiliser un index b-tree. Le hachage semble être une meilleure idée, mais il est obsolète et n'est pas répliqué via la réplication de secours à chaud. Tout avis serait grandement apprécié.
J'ai un peu expérimenté les indices suivants:
"foo_part" btree (uploaded_at) WHERE uploaded_at IS NULL
"foo_part_id" btree (id) WHERE uploaded_at IS NULL
et le planificateur de requêtes semble toujours choisir l' foo_part
index. explain analyse
donne également un résultat légèrement meilleur pour l' foo_part
indice:
Index Scan using foo_part on t1 (cost=0.28..297.25 rows=4433 width=16) (actual time=0.025..3.649 rows=4351 loops=1)
Index Cond: (uploaded_at IS NULL)
Total runtime: 4.060 ms
contre
Bitmap Heap Scan on t1 (cost=79.15..6722.83 rows=4433 width=16) (actual time=1.032..4.717 rows=4351 loops=1)
Recheck Cond: (uploaded_at IS NULL)
-> Bitmap Index Scan on foo_part_id (cost=0.00..78.04 rows=4433 width=0) (actual time=0.649..0.649 rows=4351 loops=1)
Total runtime: 5.131 ms
la source
id
par exemple un champ série ?serial
est aussi bon que n'importe lequel. Le point est de savoir s'il existe réellement des requêtes pour l'utiliser.