Vous n'êtes pas identifié(e).

#1 21/03/2018 11:51:02

Postgres.0
Membre

Requeste à optimiser

Bonjour,


depuis quelques jours, je me casse les dents sur cette requête.
Si quelqu'un peut m'aider ou me donner une piste pour l'optimiser, je lui serai reconnaissant.

Merci

SELECT ccc.logger_date,
       ccc.agg,
(SELECT string_agg( bbb.logger_date || ' ' || bbb.indice || ',' || bbb.parameter,';') AS agg_aa
 FROM
(SELECT  distinct ON (first_value( ind_parameter) OVER (partition by ind_parameter ORDER BY  logger_date))
first_value( ind_parameter) OVER (partition by ind_parameter ORDER BY  logger_date) AS indice,
parameter,logger_date
FROM logger
WHERE system_id = '1234-56789'
AND logger_date > ccc.logger_date
AND ind_parameter in ('1','2', '3', '4', '5', '6', '7', '8', '9', '10', '13', '14')
AND parameter IS NOT NULL ) bbb
 )
FROM
(SELECT logger_date, string_agg(ind_parameter || ','|| parameter,';') AS agg, system_id
FROM logger
WHERE system_id = '1234-56789'
AND ind_parameter in ('1','2', '3', '4', '5', '6', '7', '8', '9', '10', '13', '14')
AND parameter IS NOT NULL group by  logger_date, system_id
order by logger_date) ccc;
Subquery Scan on aaa  (cost=0.42..238917116.65 rows=49626 width=104) (actual time=121.370..2504513.471 rows=59651 loops=1)
   ->  GroupAggregate  (cost=0.42..12255.07 rows=49626 width=83) (actual time=0.043..894.271 rows=59651 loops=1)
         Group Key: logger_tmp.logger_date, logger_tmp.system_id
         ->  Index Scan using logger_tmp_logger_date_idx on logger_tmp  (cost=0.42..10298.19 rows=80833 width=26) (actual time=0.019..310.172 rows=87849 loops=1)
               Filter: ((parameter IS NOT NULL) AND ((system_id)::text = '1234-56789'::text) AND ((ind_parameter)::text = ANY ('{1,2,3,4,5,6,7,8,9,10,13,14}'::text[])))
               Rows Removed by Filter: 30334
   SubPlan 1
     ->  Aggregate  (cost=4814.09..4814.10 rows=1 width=32) (actual time=41.953..41.954 rows=1 loops=59651)
           ->  Bitmap Heap Scan on logger_tmp b  (cost=738.49..4350.74 rows=26477 width=15) (actual time=6.629..39.276 rows=1944 loops=59651)
                 Recheck Cond: (logger_date > aaa.logger_date)
                 Filter: (((system_id)::text = '1234-56789'::text) AND ((ind_parameter)::text > ANY ((aaa.arr)::text[])) AND ((ind_parameter)::text = ANY ('{1,2,3,4,5,6,7,8,9,10,13,14}'::text[])))
                 Rows Removed by Filter: 55358
                 Heap Blocks: exact=62729157
                 ->  Bitmap Index Scan on logger_tmp_logger_date_idx  (cost=0.00..731.87 rows=39394 width=0) (actual time=6.396..6.396 rows=57302 loops=59651)
                       Index Cond: (logger_date > aaa.logger_date)
 Planning time: 0.869 ms
 Execution time: 2504554.579 ms
(17 rows)

Dernière modification par Postgres.0 (22/03/2018 16:58:43)

Hors ligne

#2 22/03/2018 11:00:35

gleu
Administrateur

Re : Requeste à optimiser

Le problème vient de la sous-requête dans la partie SELECT. Individuellement, elle n'est exécutée qu'en 41ms mais elle est exécutée 59651 fois, donc elle prends du temps.

Je ne vois que deux façons de l'améliorer. Soit la laisser tel quel et travailler uniquement sur la sous-requête pour voir s'il manque un index qui serait plus déterminant, soit la réécrire complètement. Sur ce dernier point, à mon avis, c'est possible de le faire sans sous-requête.


Guillaume.

Hors ligne

#3 22/03/2018 11:29:30

Postgres.0
Membre

Re : Requeste à optimiser

Merci gleu,

il n y a pas d'index intéressant à rajouter, les filtres ne sont pas du tout discriminent.
Par contre, je ne vois pas comment on peut réécrire la requête sans passer par la sous requête.


Merci d'avance

Hors ligne

#4 23/03/2018 17:23:38

Postgres.0
Membre

Re : Requeste à optimiser

Si il y a un volontaire  prêt pour la réécriture de la requête (comme cité plus haut par gleu), je suis preneur.


Merci d'avance

Hors ligne

#5 24/03/2018 20:58:42

gleu
Administrateur

Re : Requeste à optimiser

Sans connaître le schéma, voire le contexte, c'est totalement utopique de croire que quelqu'un peut la réécrire à coup sûr. Tout ce qu'on peut faire, c'est deviner comment la réécrire, ce qui fera perdre du temps aux deux (vous et celui qui va tenter de vous aider). Bref, je ne vais pas me lancer dans un jeu de devinette smile


Guillaume.

Hors ligne

Pied de page des forums