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?

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.


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.