Ich habe eine sehr einfache SQL-Abfrage:
SELECT COUNT(DISTINCT x) FROM table;
Meine Tabelle hat ungefähr 1,5 Millionen Zeilen. Diese Abfrage läuft ziemlich langsam. es dauert ungefähr 7,5s im Vergleich zu
SELECT COUNT(x) FROM table;
das dauert etwa 435ms. Gibt es eine Möglichkeit, meine Abfrage zu ändern, um die Leistung zu verbessern? Ich habe versucht, zu gruppieren und regelmäßig zu zählen sowie einen Index für x zu erstellen. Beide haben die gleiche Ausführungszeit von 7,5 Sekunden.
performance
postgresql
count
distinct
ferson2020
quelle
quelle
\d
Ausgabe vonpsql
ist gut) und geben Sie die Spalte an, mit der Sie Probleme haben. Es wäre gut,EXPLAIN ANALYZE
beide Fragen zu sehen.Antworten:
Sie können dies verwenden:
Das ist viel schneller als:
quelle
COUNT(DISTINCT())
die Sortierung durchgeführt wird, ist es auf jeden Fall hilfreich, einen Index für diecolumn_name
besonders kleine Menge von zu habenwork_mem
(wobei durch Hashing eine relativ große Menge an Chargen erzeugt wird). Seitdem ist es nicht immer schlecht, COUNT (DISTINCT () _ zu verwenden, nichtCount(column)
zählt nur Nicht-Null-Werte.count(*)
zählt Zeilen. Die erste / längere zählt also auch die Nullzeile (einmal). Wechseln Sie zucount(column_name)
, damit sie sich gleich verhalten.Ergebnisse:
Der gleiche Plan wie für den CTE könnte wahrscheinlich auch mit anderen Methoden (Fensterfunktionen) erstellt werden.
quelle
Wenn Ihr Wert
count(distinct(x))
erheblich langsamercount(x)
ist, können Sie diese Abfrage beschleunigen, indem Sie die Anzahl der x-Werte in verschiedenen Tabellen beibehalten, z. B.table_name_x_counts (x integer not null, x_count int not null)
mithilfe von Triggern. Ihre Schreibleistung leidet jedoch darunter. Wenn Sie mehrerex
Werte in einer Transaktion aktualisieren , müssen Sie dies in einer expliziten Reihenfolge tun, um einen möglichen Deadlock zu vermeiden.quelle
Ich habe auch nach derselben Antwort gesucht, weil ich irgendwann total_count mit unterschiedlichen Werten zusammen mit limit / offset brauchte .
Weil es wenig schwierig ist, die Gesamtzahl mit unterschiedlichen Werten zusammen mit dem Grenzwert / Versatz zu ermitteln. Normalerweise ist es schwierig, die Gesamtzahl mit Limit / Offset zu ermitteln. Endlich habe ich den Weg gefunden -
SELECT DISTINCT COUNT(*) OVER() as total_count, * FROM table_name limit 2 offset 0;
Die Abfrageleistung ist ebenfalls hoch.
quelle