J'ai essayé COUNT(*)
une table avec 150 000 lignes qui a une clé primaire. Cela prend environ 5 minutes, j'ai donc compris qu'il s'agissait d'un problème d'indexation.
Citant le manuel PostgreSQL :
REINDEX est similaire à une suppression et recréation de l'index en ce que le contenu de l'index est reconstruit à partir de zéro. Cependant, les considérations de verrouillage sont assez différentes. REINDEX verrouille les écritures mais pas les lectures de la table parent de l'index. Il prend également un verrou exclusif sur l'index spécifique en cours de traitement, qui bloquera les lectures qui tentent d'utiliser cet index (...) Le CREATE INDEX suivant verrouille les écritures mais pas les lectures; comme l'index n'est pas là, aucune lecture ne tentera de l'utiliser, ce qui signifie qu'il n'y aura pas de blocage mais les lectures pourraient être forcées dans des analyses séquentielles coûteuses.
D'après votre propre expérience, pouvez-vous dire:
- est
REINDEXING
dangereux? Peut-il nuire à la cohérence des données? - Cela peut-il prendre beaucoup de temps?
- Est-ce une solution probable à mon scénario?
Mise à jour:
La solution qui a fonctionné pour nous était de recréer le même index avec un nom différent, puis de supprimer l'ancien index.
La création de l'index est très rapide, et nous avons réduit la taille de l'index de 650 Mo à 8 Mo. L'utilisation d'un COUNT(*)
avec between
ne prend que 3 secondes.
COUNT(*)
est le meilleur choix:If you are using count(*), the database is free to use any column to count, which means it can pick the smallest covering index to scan (note that this is why count(*) is much better than count(some_field), as long as you don't care if null values of some_field are counted). Since indexes often fit entirely in memory, this means count(*) is often very fast.