PostgreSQL: COUNT (*) verwendet einen sequentiellen Scan, keinen Index

12

Warum durchsucht PostgreSQL die Tabelle nacheinander nach COUNT(*)Abfragen, obwohl es einen sehr kleinen und indizierten Primärschlüssel gibt?

Adam Matan
quelle

Antworten:

15

Die offiziellen Wiki-Seiten geben darauf eine Antwort:

[...] Der Grund, warum dies langsam ist, hängt mit der MVCC-Implementierung in PostgreSQL zusammen. Die Tatsache, dass mehrere Transaktionen unterschiedliche Zustände der Daten anzeigen können, bedeutet, dass es für "COUNT (*)" keine einfache Möglichkeit gibt, Daten in der gesamten Tabelle zusammenzufassen. In gewisser Weise muss PostgreSQL alle Zeilen durchlaufen. Dies führt normalerweise zu einem sequentiellen Scan, der Informationen zu jeder Zeile in der Tabelle liest. [...]

Darüber hinaus können Sie eine ANALYSE versuchen , um die Informationen für den Abfrageplaner neu zu erstellen .

Sie sollten eine bessere Leistung erzielen, COUNT(an uniquly indexed field)aber wenn dies sehr groß ist, ist ein seq-Scan die einzige Möglichkeit, dies zu tun.

Wenn Sie sehr schnelle Nummern benötigen und keine Angst haben, das Schema abzufragen, können Sie Folgendes tun

SELECT reltuples FROM pg_class WHERE oid = 'your_table'::regclass

Verlassen Sie sich jedoch nicht auf diese Werte, da es sich nur um eine "geschätzte" (obwohl häufig exakte) Anzahl von Tupeln in der Tabelle handelt.

DrColossos
quelle
Das halte ich nicht für richtig. Ich habe nirgendwo etwas gelesen, wo COUNT(pk)die Leistung verbessert wird. Ich denke, es wird immer einen seq-scan machen
vol7ron
1
Wenn Sie keine where-Klausel verwenden, wird ein seq-Scan durchgeführt. Mit einer ausreichend ausgewählten where-Klausel KANN postgresql einen Index verwenden, aber denken Sie daran, dass dieser zur Tabelle zurückkehren wird, um die Sichtbarkeit der Tupel zu überprüfen, über die er berichtet.
Scott Marlowe