首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Postgres聚合查询太慢

问Postgres聚合查询太慢
EN

Stack Overflow用户
提问于 2021-03-03 01:43:32
回答 1查看 115关注 0票数 0

我有一个查询,它正在生成趋势响应,并为我提供各种日期的设备计数。该查询将超过近500k行。该表有近1750万条记录。我已经根据id对表进行了分区,因此它只能查找特定的分区,但仍然非常慢。每个分区有近200k条记录。有什么办法可以提高这个的性能吗?

查询

代码语言:javascript
复制
select start_date,end_date,average, fail_count, warning_count,pass_count, average from
   (
   select generate_series(timestamp '2021-01-18 00:00:00', timestamp '2021-02-12 00:00:00', interval  '1 day')::date) t(start_date)  
   LEFT  JOIN (
      SELECT  start_date, end_date, avg(score) as average 
        , count(*) FILTER (WHERE status = 'Fail')    AS fail_count
    , count(*) FILTER (WHERE status = 'Warning') AS warning_count
    , count(*) FILTER (WHERE status = 'Pass')    AS pass_count        
   FROM   performance.tenant_based scd  join performance.hierarchy dh on dh.id = scd.id and dh.tag = scd.tag 
    where dh.parent_id in (0,1,2,3,4,5,6,7,8,9,10) and dh.child_id in (0,1,2,3,4,5,6,7,8,9,10) and dh.desc in ('test') 
    and dh.id ='ita68f0c03880e4c6694859dfa74f1cdf6' AND  start_date >= '2021-01-18 00:00:00'  -- same date range as above
    AND    start_date <= '2021-02-12 00:00:00'    
   GROUP  BY 1,2
   ) s USING (start_date)
ORDER  BY 1;

查询计划如下

代码语言:javascript
复制
Sort  (cost=241350.02..241850.02 rows=200000 width=104) (actual time=3453.888..3453.890 rows=26 loops=1)
  Sort Key: (((((generate_series('2021-01-18 00:00:00'::timestamp without time zone, '2021-02-12 00:00:00'::timestamp without time zone, '1 day'::interval)))::date))::timestamp without time zone)
  Sort Method: quicksort  Memory: 28kB
  ->  Merge Left Join  (cost=201014.95..212802.88 rows=200000 width=104) (actual time=2901.012..3453.867 rows=26 loops=1)
        Merge Cond: ((((generate_series('2021-01-18 00:00:00'::timestamp without time zone, '2021-02-12 00:00:00'::timestamp without time zone, '1 day'::interval)))::date) = scd.start_date)
        ->  Sort  (cost=79.85..82.35 rows=1000 width=4) (actual time=0.015..0.024 rows=26 loops=1)
              Sort Key: (((generate_series('2021-01-18 00:00:00'::timestamp without time zone, '2021-02-12 00:00:00'::timestamp without time zone, '1 day'::interval)))::date)
              Sort Method: quicksort  Memory: 26kB
              ->  Result  (cost=0.00..20.02 rows=1000 width=4) (actual time=0.003..0.009 rows=26 loops=1)
                    ->  ProjectSet  (cost=0.00..5.02 rows=1000 width=8) (actual time=0.002..0.006 rows=26 loops=1)
                          ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.000..0.000 rows=1 loops=1)
        ->  Materialize  (cost=200935.11..209318.03 rows=40000 width=72) (actual time=2900.992..3453.789 rows=25 loops=1)
              ->  Finalize GroupAggregate  (cost=200935.11..208818.03 rows=40000 width=72) (actual time=2900.990..3453.771 rows=25 loops=1)
                    Group Key: scd.start_date, scd.end_date
                    ->  Gather Merge  (cost=200935.11..207569.38 rows=49910 width=72) (actual time=2879.365..3453.827 rows=75 loops=1)
                          Workers Planned: 2
                          Workers Launched: 2
                          ->  Partial GroupAggregate  (cost=199935.08..200808.51 rows=24955 width=72) (actual time=2686.465..3228.313 rows=25 loops=3)
                                Group Key: scd.start_date, scd.end_date
                                ->  Sort  (cost=199935.08..199997.47 rows=24955 width=25) (actual time=2664.518..2860.477 rows=1666667 loops=3)
                                      Sort Key: scd.start_date, scd.end_date
                                      Sort Method: external merge  Disk: 59840kB
                                      ->  Hash Join  (cost=44891.11..198112.49 rows=24955 width=25) (actual time=111.653..1817.228 rows=1666667 loops=3)
                                            Hash Cond: (scd.tag = (dh.tag)::text)
                                            ->  Append  (cost=0.00..145159.33 rows=2083333 width=68) (actual time=0.006..591.818 rows=1666667 loops=3)
                                                  ->  Parallel Seq Scan on ita68f0c03880e4c6694859dfa74f1cdf6 scd  (cost=0.00..145159.33 rows=2083333 width=68) (actual time=0.006..455.525 rows=1666667 loops=3)
                                                        Filter: ((start_date >= '2021-01-18 00:00:00'::timestamp without time zone) AND (start_date <= '2021-02-12 00:00:00'::timestamp without time zone) AND ((id)::text = 'ita68f0c03880e4c6694859dfa74f1cdf6'::text))
                                            ->  Hash  (cost=44638.71..44638.71 rows=20192 width=45) (actual time=111.502..111.502 rows=200000 loops=3)
                                                  Buckets: 65536 (originally 32768)  Batches: 8 (originally 1)  Memory Usage: 3585kB
                                                  ->  Bitmap Heap Scan on hierarchy dh  (cost=1339.01..44638.71 rows=20192 width=45) (actual time=26.542..62.078 rows=200000 loops=3)
                                                        Recheck Cond: (((id)::text = 'ita68f0c03880e4c6694859dfa74f1cdf6'::text) AND (parent_id = ANY ('{0,1,2,3,4,5,6,7,8,9,10}'::integer[])) AND (child_id = ANY ('{0,1,2,3,4,5,6,7,8,9,10}'::integer[])) AND ((desc)::text = 'test'::text))
                                                        Heap Blocks: exact=5717
                                                        ->  Bitmap Index Scan on hierarchy_id_region_idx  (cost=0.00..1333.96 rows=20192 width=0) (actual time=25.792..25.792 rows=200000 loops=3)
                                                              Index Cond: (((id)::text = 'ita68f0c03880e4c6694859dfa74f1cdf6'::text) AND (parent_id = ANY ('{0,1,2,3,4,5,6,7,8,9,10}'::integer[])) AND (child_id = ANY ('{0,1,2,3,4,5,6,7,8,9,10}'::integer[])) AND ((desc)::text = 'test'::text))
Planning time: 0.602 ms
Execution time: 3463.440 ms
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-04 23:34:21

在经历了几次跟踪和错误之后,我们找到了这个查询的物化视图。查询正在扫描的行数几乎是500k+,并且没有索引和分区。我们调整了上面的查询,以创建一个物化视图,然后在其上执行select操作。我们现在是96ms。此问题中查询的广义物化视图如下所示。

代码语言:javascript
复制
CREATE MATERIALIZED VIEW performance.daily_trends
TABLESPACE pg_default
AS SELECT s.id,
    d.parent_id,
    d.child_id,  
    d.desc,
    s.start_date,
    s.end_date,
    count(*) FILTER (WHERE s.overall_status::text = 'Fail'::text) AS fail_count,
    count(*) FILTER (WHERE s.overall_status::text = 'Warning'::text) AS warning_count,
    count(*) FILTER (WHERE s.overall_status::text = 'Pass'::text) AS pass_count,
    avg(s.score) AS average_score
   FROM performance.tenant_based  s
     JOIN performance.hierarchy  d ON s.id::text = d.id::text AND s.tag = d.tag::text
  WHERE s.start_date >= (CURRENT_DATE - 45) AND s.start_date <= CURRENT_DATE
  GROUP BY s.id, d.parent_id, d.child_id, d.desc, s.start_date, s.end_date
WITH DATA;

感谢所有试图在这方面提供帮助的人。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66444457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档