Bonjour à tous,

Je souhaiterai optimiser une requête postegre qui prend plusieurs dixaines de seconde à être exécutée.. Ci après la requête :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
select
     f.timestamp::date as date,
       user_id,
       activity_type,
       f.container_id as group_id,
       (
          select
              string_agg(distinct("userId"), ',') as group_owners
            from
              jusers_groups_copy g
            where
              g.place_id = f.container_id
              and state like 'owner'
        ) as group_owners
     from
       fact_activity f
     where
       f.container_type like '700'
       and f.timestamp::date < to_date('2016-09-05', 'YYYY-MM-DD')
     group by
      date, user_id, activity_type, group_id
     order by
      date, user_id, activity_type, group_id

Etant complètement nouveau sur postgre, j'ai utilisé un explain et un analyse mais il m'est compliqué de comprendre le résultat :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
"Group  (cost=7029.62..651968.20 rows=17843 width=27) (actual time=431.017..4513.973 rows=11483 loops=1)"
"  Buffers: shared hit=139498 read=411, temp read=255 written=255"
"  ->  Sort  (cost=7029.62..7074.90 rows=18111 width=27) (actual time=430.630..667.098 rows=54660 loops=1)"
"        Sort Key: ((f."timestamp")::date), f.user_id, f.activity_type, f.container_id"
"        Sort Method: external merge  Disk: 2008kB"
"        Buffers: shared hit=1702 read=411, temp read=255 written=255"
"        ->  Seq Scan on fact_activity f  (cost=0.00..5748.76 rows=18111 width=27) (actual time=0.107..188.827 rows=54660 loops=1)"
"              Filter: ((container_type ~~ '700'::text) AND (("timestamp")::date < to_date('2016-09-05'::text, 'YYYY-MM-DD'::text)))"
"              Rows Removed by Filter: 125414"
"              Buffers: shared hit=1691 read=411"
"  SubPlan 1"
"    ->  Aggregate  (cost=36.12..36.13 rows=1 width=5) (actual time=0.315..0.318 rows=1 loops=11483)"
"          Buffers: shared hit=137796"
"          ->  Seq Scan on jusers_groups_copy g  (cost=0.00..36.09 rows=11 width=5) (actual time=0.041..0.266 rows=13 loops=11483)"
"                Filter: ((state ~~ 'owner'::text) AND (place_id = f.container_id))"
"                Rows Removed by Filter: 1593"
"                Buffers: shared hit=137796"
"Total runtime: 4536.074 ms"
J'ai constaté que la durée de la requête était drastiquement réduite lorsque j'enlevais le select imbriqué :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
(
          select
              string_agg(distinct("userId"), ',') as group_owners
            from
              jusers_groups_copy g
            where
              g.place_id = f.container_id
              and state like 'owner'
        ) as group_owners
De plus, les tables ne disposent d'aucun index.

Ainsi, j'aurai souhaité savoir si le pb venait de ce manque d'index ou s'il était possible d'optimiser la requête d'une quelconque façon ?
Je souhaiterai en découvrir d'avantage sur ce ralentissement, pourriez vous m'éclairer sur le fait que la requête met beaucoup de temps à s'exécuter ?

Merci d'avance

Koven