J'ai posté votre plan de requête sur expliquer.depesz.com, jetez un œil.
Les estimations du planificateur de requêtes sont terriblement erronées à certains endroits.Avez-vous exécuté ANALYZE
récemment ?
Lisez les chapitres du manuel sur les statistiques utilisées par le planificateur et les constantes de coût du planificateur. Portez une attention particulière aux chapitres sur random_page_cost
et default_statistics_target
.
Vous pourriez essayer :
ALTER TABLE diplomas ALTER COLUMN number SET STATISTICS 1000;
ANALYZE diplomas;
Ou allez encore plus haut pour une table avec 10 millions de lignes. Cela dépend de la distribution des données et des requêtes réelles . Expérience. La valeur par défaut est 100, la valeur maximale est 10 000.
Pour une base de données de cette taille, seulement 1 ou 5 Mo de work_mem
ne suffisent généralement pas. Lisez la page Wiki de Postgres sur Tuning Postgres à laquelle @aleroot est lié.
Comme votre requête nécessite 430 104 Ko de mémoire sur le disque selon EXPLAIN
sortie, vous devez définir work_mem
à quelque chose comme 500 Mo ou plus pour permettre le tri en mémoire. La représentation des données en mémoire nécessite un peu plus d'espace que la représentation sur disque. Vous pourriez être intéressé par ce que Tom Lane a récemment publié à ce sujet.
Augmenter work_mem
juste un peu, comme vous avez essayé, n'aidera pas beaucoup ou peut même ralentir. Le régler sur élevé à l'échelle mondiale peut même faire mal, en particulier avec un accès simultané. Plusieurs sessions peuvent se priver mutuellement de ressources. Allouer plus à un objectif enlève de la mémoire à un autre si la ressource est limitée. La meilleure configuration dépend de la situation dans son ensemble.
Pour éviter les effets secondaires, ne le définissez qu'assez élevé localement dans votre session, et temporairement pour la requête :
SET work_mem = '500MB';
Réinitialisez-le ensuite à vos valeurs par défaut :
RESET work_mem;
Ou utilisez SET LOCAL
pour le définir uniquement pour la transaction en cours pour commencer.