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.
la source
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.
Je ne suis pas sûr de la meilleure réponse pour vous. Cependant, ce fil semble offrir de bonnes suggestions: n http://postgresql.1045698.n5.nabble.com/count-performance-issue-td2067873.html
Une note est que vous pouvez implémenter un TRIGGER pour maintenir le nombre de lignes dans une table séparée (si COUNT (*) est appelé fréquemment par vos applications).
Quelques-unes des réponses suggèrent que cela est symptomatique d'une base de données qui n'a pas été aspirée assez récemment (suggérant que l'autovacuum est désactivé sur votre serveur ou pour cette base de données en particulier)?
Une autre suggestion ressemble à ceci:
Et quelqu'un identifié comme A. Kretschmer note:
Non. L'implémentation d'index actuelle ne contient aucune information sur la visibilité des lignes dans la transaction en cours. Vous devez analyser l'ensemble de la table de données pour savoir si la ligne actuelle est visible dans la transaction en cours.
... soutenant mon commentaire sur les autorisations au niveau des lignes étant un problème de performances.
Ma recherche a également révélé WikiVS: MySQL vs PostgreSQL: COUNT (*) .
Vous pouvez parcourir les autres résultats que j'ai trouvés en utilisant Google: performances de comptage postgresql (*)
la source