Ich habe versucht, COUNT(*)
eine Tabelle mit 150.000 Zeilen, die einen Primärschlüssel hat. Es dauert ungefähr 5 Minuten, also habe ich herausgefunden, dass dies ein Indizierungsproblem ist.
Zitieren des PostgreSQL-Handbuchs :
REINDEX ähnelt dem Löschen und Neuerstellen des Index, indem der Indexinhalt von Grund auf neu erstellt wird. Die Überlegungen zum Sperren sind jedoch recht unterschiedlich. REINDEX sperrt Schreibvorgänge, jedoch keine Lesevorgänge für die übergeordnete Tabelle des Index. Es wird auch eine exklusive Sperre für den bestimmten Index benötigt, der verarbeitet wird. Dadurch werden Lesevorgänge blockiert, die versuchen, diesen Index zu verwenden (...). Da der Index nicht vorhanden ist, versucht kein Lesevorgang, ihn zu verwenden. Dies bedeutet, dass keine Blockierung erfolgt, Lesevorgänge jedoch möglicherweise zu teuren sequenziellen Scans gezwungen werden.
Kannst du aus eigener Erfahrung sagen:
- ist
REINDEXING
gefährlich? Kann dies die Datenkonsistenz beeinträchtigen? - Kann es viel Zeit dauern?
- Ist es eine wahrscheinliche Lösung für mein Szenario?
Aktualisieren:
Die für uns funktionierende Lösung bestand darin, denselben Index mit einem anderen Namen neu zu erstellen und dann den alten Index zu löschen.
Die Indexerstellung ist sehr schnell und wir haben die Indexgröße von 650 MB auf 8 MB reduziert. Die Verwendung von a COUNT(*)
mit between
dauert nur 3 Sekunden.
quelle
COUNT(*)
ist die beste Wahl: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.
Ich bin mir nicht sicher, welche Antwort für Sie die beste ist. Dieser Thread scheint jedoch einige gute Vorschläge zu bieten: n http://postgresql.1045698.n5.nabble.com/count-performance-issue-td2067873.html
Eine Anmerkung ist, dass Sie einen TRIGGER implementieren könnten, um die Zeilenanzahl in einer separaten Tabelle zu verwalten (wenn COUNT (*) von Ihren Anwendungen häufig aufgerufen würde).
Einige der Antworten deuten darauf hin, dass dies symptomatisch für eine Datenbank ist, die in letzter Zeit nicht ausreichend gesaugt wurde (was darauf hindeutet, dass das automatische Saugen auf Ihrem Server oder speziell für diese Datenbank deaktiviert ist)?
Ein weiterer Vorschlag sieht so aus:
Und jemand, der als A. Kretschmer identifiziert wurde, bemerkt:
Nein. Die aktuelle Indeximplementierung enthält keine Informationen zur Zeilensichtbarkeit innerhalb der aktuellen Transaktion. Sie müssen die gesamte Datentabelle durchsuchen, um festzustellen, ob die aktuelle Zeile in der aktuellen Transaktion sichtbar ist.
... unterstütze ich meinen Kommentar zu Berechtigungen auf Zeilenebene, die ein Leistungsproblem darstellen.
Meine Suche ergab auch WikiVS: MySQL vs. PostgreSQL: COUNT (*) .
Die anderen Ergebnisse, die ich mithilfe von Google gefunden habe, können Sie nachlesen : postgresql count (*) performance
quelle