Question Solution pour accélérer une requête SELECT DISTINCT lente dans Postgres


La requête est essentiellement:

SELECT DISTINCT "my_table"."foo" from "my_table" WHERE...

Prétendant que je suis certain à 100% du DISTINCT une partie de la requête est la raison pour laquelle elle s'exécute lentement, j'ai omis le reste de la requête pour éviter toute confusion, car c'est la lenteur de la partie distincte qui m'intéresse principalement (distinct est toujours source de lenteur).

La table en question a 2,5 millions de lignes de données. le DISTINCT  est nécessaire à des fins non répertoriées ici (parce que je ne veux pas renvoyer une requête modifiée, mais plutôt des informations générales sur l'exécution plus rapide de requêtes distinctes au SGBD niveau, si possible).

Comment puis-je faire DISTINCT exécuter plus rapidement (en utilisant spécifiquement Postgres 9) sans modifier le SQL (c.-à-d. que je ne peux pas modifier ce SQL entrant, mais avoir accès à l'optimisation au niveau de la base de données)?


21
2017-07-06 15:16


origine


Réponses:


Votre DISTINCT provoque le tri des lignes de sortie afin de trouver des doublons. Si vous placez un index sur la ou les colonnes sélectionnées par la requête, la base de données peut être en mesure de les lire dans l’ordre des index et de sauvegarder l’étape de tri. Cela dépendra beaucoup des détails de la requête et des tableaux impliqués. Vous dites que vous connaissez le problème avec le DISTINCT, cela limite vraiment la portée des réponses disponibles.


13
2017-07-06 15:29



Souvent, vous pouvez faire fonctionner ces requêtes plus rapidement en travaillant distinct en utilisant un group by au lieu:

select my_table.foo 
from my_table 
where [whatever where conditions you want]
group by foo;

22
2017-07-06 15:25



Vous pouvez essayer d'augmenter le paramètre work_mem, en fonction de la taille de votre jeu de données. Cela peut entraîner le basculement du plan de requête en agrégats de hachage, généralement plus rapides.

Mais avant de le définir trop haut globalement, lisez-le d'abord. Vous pouvez facilement exploser votre serveur, car le max_connections le réglage agit comme un multiplicateur de ce nombre.

Cela signifie que si vous deviez définir work_mem = 128MB et vous définissez max_connections = 100 (par défaut), vous devriez avoir plus de 12,8 Go de RAM. Vous êtes essentiellement en train de dire au serveur qu'il peut en utiliser autant pour effectuer des requêtes (même en ne considérant aucune autre utilisation de la mémoire par Postgres ou autre).


4
2017-07-08 00:40