J'ai une requête SQL très simple:
SELECT COUNT(DISTINCT x) FROM table;
Ma table contient environ 1,5 million de lignes. Cette requête s'exécute assez lentement; cela prend environ 7,5 s, comparé à
SELECT COUNT(x) FROM table;
ce qui prend environ 435 ms. Existe-t-il un moyen de modifier ma requête pour améliorer les performances? J'ai essayé de regrouper et de faire un comptage régulier, ainsi que de mettre un index sur x; les deux ont le même temps d'exécution de 7,5 s.
performance
postgresql
count
distinct
ferson2020
la source
la source
\d
sortie depsql
est la bonne) et précisez la colonne avec laquelle vous avez un problème. Ce serait bien de voir lesEXPLAIN ANALYZE
deux requêtes.Réponses:
Vous pouvez utiliser ceci:
C'est beaucoup plus rapide que:
la source
COUNT(DISTINCT())
effectue le tri, il sera certainement utile d'avoir un index sur le, encolumn_name
particulier avec une quantité relativement petite dework_mem
(où le hachage produira une quantité relativement importante de lots). Depuis cela, il n'est pas toujours mauvais d'utiliser COUNT (DISTINCT () _, n'est-ce pas?Count(column)
ne compte que les valeurs non nulles.count(*)
compte les lignes. Ainsi, le premier / le plus long comptera également la ligne nulle (une fois). Remplacez parcount(column_name)
pour qu'ils se comportent de la même manière.Résultats:
Le même plan que pour le CTE pourrait probablement aussi être produit par d'autres méthodes (fonctions de fenêtre)
la source
Si votre
count(distinct(x))
est beaucoup plus lent qu'alors,count(x)
vous pouvez accélérer cette requête en conservant le nombre de valeurs x dans différentes tables, par exempletable_name_x_counts (x integer not null, x_count int not null)
, à l'aide de déclencheurs. Mais vos performances d'écriture en souffriront et si vous mettez à jour plusieursx
valeurs en une seule transaction, vous devrez le faire dans un ordre explicite pour éviter un éventuel blocage.la source
Je cherchais également la même réponse, car à un moment donné, j'avais besoin de total_count avec des valeurs distinctes avec limite / offset .
Parce que c'est peu difficile à faire - Pour obtenir le nombre total avec des valeurs distinctes avec limite / décalage. Il est généralement difficile d'obtenir le nombre total avec limite / décalage. Enfin j'ai eu le moyen de faire -
SELECT DISTINCT COUNT(*) OVER() as total_count, * FROM table_name limit 2 offset 0;
Les performances des requêtes sont également élevées.
la source