Bonjour,
J'ai un gros problème de performance avec un cas que je rencontre souvent. Peut être un cas d'école ?
Pour être plus clair j'ai préparé un exemple :
J'ai les chiffres des sociétés année par année.
Je souhaite extraire le dernier chiffre d'affaires pour chaque société.
Je fais donc une sous-requête avec un group by.
Ca fonctionne très bien ... sauf que j'ai 100 000 lignes. Et là, ça me fait une recherche séquentiel sur 100 000 lignes. Comme je veux mettre toujours dans une jointure c'est extrèmement lourd.
Ca doit être un problème très courant.
Est ce que vous connaissez une solution qui soit meilleur que la mienne ?
Merci d'avance
CREATE TABLE societe (
id_societe serial,
nom varchar
);
CREATE TABLE chiffre_affaire (
id_chiffre_affaire serial,
id_societe integer,
annee integer,
valeur integer
);
CREATE INDEX index_chiffre_affaire_id_societe ON chiffre_affaire USING btree (id_societe);
CREATE INDEX index_chiffre_affaire_annee ON chiffre_affaire USING btree (annee);
INSERT INTO societe VALUES (1, 'dupont');
INSERT INTO societe VALUES (2, 'durant');
INSERT INTO chiffre_affaire (id_societe, annee, valeur) VALUES (1, 2000, 100);
INSERT INTO chiffre_affaire (id_societe, annee, valeur) VALUES (1, 2001, 120);
INSERT INTO chiffre_affaire (id_societe, annee, valeur) VALUES (1, 2002, 130);
INSERT INTO chiffre_affaire (id_societe, annee, valeur) VALUES (1, 2003, 125);
INSERT INTO chiffre_affaire (id_societe, annee, valeur) VALUES (1, 2003, 115);
INSERT INTO chiffre_affaire (id_societe, annee, valeur) VALUES (2, 2002, 200);
INSERT INTO chiffre_affaire (id_societe, annee, valeur) VALUES (2, 2003, 210);
INSERT INTO chiffre_affaire (id_societe, annee, valeur) VALUES (2, 2003, 220);
EXPLAIN ANALYSE
SELECT societe.id_societe, MAX(valeur) as valeur, MAX(nom) as nom
FROM societe
LEFT JOIN chiffre_affaire
ON chiffre_affaire.id_societe=societe.id_societe
AND annee = (SELECT MAX(annee) FROM chiffre_affaire as a WHERE a.id_societe=chiffre_affaire.id_societe)
GROUP BY societe.id_societe;
Partager