Vous n'êtes pas identifié(e).
Pages : 1
Bonjour,
L'index ne sert à rien dans ce cas précis, puisque vous récupérez l'intégralité des données, pour les regrouper par année.
Vous lisez 25M de lignes pour n'en afficher que 15.
Bonjour,
Oui effectivement, c'est logique que l'index ne soit pas utilisé.
(J'ai confondu avec la première requête qui effectue un SELECT DISTINCT annee_episode FROM episode, où là l'index n'est pas utilisé. Mais il semblerait, après recherche que le "DISTINCT" chez PostgreSQL ne se contente pas de lire les valeurs de l'index et fonctionne différemment de certains autres SGBD qui peuvent être plus rapide sur ce genre de requêtes).
Cette requête demande deux choses : du CPU (pour le calcul du hachage, noeud HashAggregate) et des IO pour la lecture de la table (SeqScan).
Malgré que la majorité soit lue en dehors du cache de PostgreSQL, cela ne provoque aucune lecture sur disque (colonne bi à 0 dans la sortie du vmstat). Autrement dit, le cache du système contient toute la table. Donc, de ce côté, on ne peut pas faire mieux.
Au niveau CPU, on ne peut rien faire de particulier à ma connaissance. À la rigueur, le hachage peut se faire sur disque mais ça n'a pas l'air d'être le cas ici. D'ailleurs la colonne bo du vmstat est à 0.
Pour cette requête précise, sur votre système, je crois que vous arrivez au mieux de ce que vous pouvez espérer.
Bonjour gleu,
Merci pour ces précisions. Effectivement j'étais assez surpris de voir qu'il n'y ait aucun accès disque, donc tout se fait au niveau du cache.
Quelles seraient les solutions alors pour obtenir de meilleurs résultats ?
Pré-calculer les résultats ?
Bonjour,
Tout d'abord, je tiens à vous remercier pour cette réponse.
Il est clair que ces résultats me semblaient étrange.
Je viens d'exécuter un VACUUM FULL sur la table en question. Et les résultats se sont nettement amélioré, bien qu'encore en dessous de ce que j'attendais.
Je comprends bien le principe du VACUUM, mais j'ai du mal à comprendre comment une requête peut passer de 1451904ms à 14794ms suite à un VACUUM FULL ? (c'est un point à étudier aussi de mon côté)
Pour la version de PostgreSQL, c'est un PostgreSQL v9.2.3.
(Plus précisement: PostgreSQL 9.2.3 on x86_64-unknown-linux-gnu, compiled by gcc-4.4.real (Debian 4.4.5-8) 4.4.5, 64-bit)
Concernant la seconde requête :
SELECT annee_episode, COUNT (*) AS nombre_episode FROM episode GROUP BY annee_episode ;
Cette requête s'exécute en ~14794ms.
Le plan d'exécution est le suivant :
HashAggregate (cost=708330.08..708330.23 rows=15 width=4) (actual time=19333.123..19333.130 rows=15 loops=1)
Buffers: shared hit=1944 read=331388
-> Seq Scan on episode (cost=0.00..583330.72 rows=24999872 width=4) (actual time=0.100..6677.270 rows=24999871 loops=1)
Buffers: shared hit=1944 read=331388
Total runtime: 19333.739 ms
Il semblerait que l'index ne soit pas utilisé pour cette requête, il doit être trop couteux pour ce cas de figure.
J'ai également monté le shared_buffer à 2GB, mais il semblerait que ce n'est pas là que se trouve le ralentissement (pour cette requête en tout cas).
Enfin, voici un aperçu du vmstat durant l'exécution de la requête :
Si je ne me trompe pas, le processeur est utilisé à 25% maximum, ça ne swap pas.
Est-t'il possible d'améliorer le temps d'exécution de cette requête ?
Est-ce qu'un paramètre (BDD, système, environnement) limite les performances d'une manière ou d'une autre ?
Merci,
PommePote
Bonjour à tous,
A la suite de plusieurs jours de test de PostgreSQL sur une base de données relativement "volumineuse" (25 millions de lignes), j'obtiens des performances assez moyenne en lecture.
J'aurai aimé obtenir de l'aide pour comprendre ces performances relativement faible, sachant que PostgreSQL est en phase de passer au pétabyte (http://www.postgresqlfr.org/pgday2013:v … postgresql) et surtout comment optimiser la configuration de mon PostgreSQL/Machine/Requête/Données pour améliorer ces performances.
La machine utilisée (VM dans le Cloud) est une Linux en 64bits avec 8Go de RAM & 8 cœurs cadencé à 2GHz.
La configuration PostgreSQL a été modifiée comme suit :
effective_cache_size = 5GB
shared_buffers = 300MB
work_mem = 10MB
maintenance_work_mem = 256MB
max_connections = 50
checkpoint_segments = 32
checkpoint_completion_target = 0.9
random_page_cost = 3.0
Pour vous donner un exemple des performances que l'on obtient :
Pour la table suivante, comprenant 25 millions de lignes, dont la structure est :
CREATE TABLE episode
(
id_episode serial NOT NULL,
...
annee_episode integer,
CONSTRAINT episode_pk PRIMARY KEY (id_episode)
)
WITH ( OIDS=FALSE );CREATE INDEX annee_idx ON episode USING btree (annee_episode);
La requête suivante met plus de 772074ms:
SELECT DISTINCT annee_episode FROM episode ;
De même que la requête suivante s'exécute en plus de 1451904ms:
SELECT annee_episode, COUNT (*) AS nombre_episode FROM episode GROUP BY annee_episode ;
Ce qui reste étrange, c'est que lorsque je scrute les processus système, je remarque que le CPU n'est utilisé au maximum qu'à 5% de sa capacité...
Est-ce que ces performances vous semble "normales" vis-à-vis du nombre de lignes ?
(Quand on sait que leboncoin.fr utilise PostgreSQL, je pense que notre volumétrie à côté est minuscule et nos performances bien moindres...)
Peut-être est-ce lié aux performances de la machine (accès au disque ?, ... ?) ?
Merci de votre aide,
PommePote
Pages : 1