postgresql COUNT(DISTINCT ...) très lent

J'ai une question très simple requête SQL:

SELECT COUNT(DISTINCT x) FROM table;

Ma table a environ 1,5 million de lignes. Cette requête est en cours d'exécution assez lentement; il faut environ 7,5 s, par rapport à

 SELECT COUNT(x) FROM table;

qui prend environ 435ms. Est-il possible de modifier ma requête pour améliorer les performances? J'ai essayé de regroupement et de pratiquer régulièrement un comte, ainsi que de mettre un index sur x; les deux ont le même 7,5 s de temps d'exécution.

  • Je ne le pense pas. Obtenir les valeurs distinctes de 1,5 million de lignes est juste va être lent.
  • Je l'ai juste essayé en C#, l'obtention de valeurs distinctes de 1,5 million de nombres entiers à partir de la mémoire prend plus d'une seconde sur mon ordinateur. Donc, je pense que vous êtes probablement hors de la chance.
  • Le plan de requête dépendra très largement de la structure de la table (index) et le réglage de la mise au point des constantes (de travail)mem, effective_cache_size, random_page_cost). Avec raisonnable de réglage de la requête pourrait être exécuté en moins d'une seconde.
  • Pourriez-vous être plus précis? Ce que l'index et le réglage des constantes seraient nécessaires pour l'obtenir à moins d'une seconde? Pour des raisons de simplicité, supposons que c'est un tableau à deux colonnes avec une clé primaire sur la première colonne y, et je suis en train de faire cette " distincte de la requête sur une deuxième colonne x de type int, avec 1,5 million de lignes.
  • Je suis juste à expérimenter: votre yery me coûte 1,7 s; distinct(val, count*) coûte environ 400 ms. Un CTE va sans doute aider le planificateur. BRB.
  • Encore une fois, pourriez-vous être précis avec ce genre de CTE aider le planificateur?
  • Deux pensées ... il pourrait être possible d'obtenir une approximation par la pratique "expliquer select distinct val de table" et de voir combien de lignes le planificateur de l'estime. L'autre pensée ... devrait probablement possible d'une façon ou d'une autre pour trouver le nombre de différentes entrées dans l'index lui-même. Malheureusement je n'ai pas de temps à les étudier pour le moment. Ah, troisième suggestion ... à l'aide d'un redondant stats table avec un compteur, mise à jour par un déclencheur. Aucune des suggestions sont très belle, cependant. Ayant un index, il faut vraiment être possible de faire le décompte relativement rapide...
  • Le CTE est plus ou moins un truc pour garder le comte+distinctes dans les différentes couches (et la cause de la "hash" plan pour être utilisé) hachés plan a besoin de quelques work_mem; réglage work_mem=64; force d'un index (ou tableau) de balayage, qui est environ deux fois plus lent. LOL, j'ai juste prouvé que posttgres est plus rapide que le C# 😉
  • Avec la même requête, je ne suis pas à l'aide de la "hachage" plan; je suis "unique", "groupe", "trier".
  • Quelle est votre version de postgres?
  • Mon postgres version 9.1.
  • S'il vous plaît, inclure la définition de la table avec tous les indices (\d sortie de psql est bonne) et précise la colonne que vous avez un problème avec. Il serait bon de voir EXPLAIN ANALYZE de deux requêtes.

InformationsquelleAutor ferson2020 | 2012-06-28