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.
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.