加快此查询以创建物化视图?

时间:2015-03-26 12:01:08

标签: postgresql

我在OSX上使用Postgres 9.4,内存为16GB。我正在Postgres表上创建一个物化视图,但创建速度非常慢,我想知道是否有任何方法可以加快速度。

这是基础表,显示了支出项目和组织:

Table "public.spending_item"
      Column       |          Type           |                             Modifiers
-------------------+-------------------------+--------------------------------------------------------------------
 id                | integer                 | not null default nextval('spending_item_id_seq'::regclass)
 presentation_code | character varying(15)   | not null
 presentation_name | character varying(1000) | not null
 total_items       | integer                 | not null
 actual_cost       | double precision        | not null
 processing_date   | date                    | not null
 organisation_id   | character varying(9)    | not null

        Table "public.organisation"
  Column   |          Type          | Modifiers
-----------+------------------------+-----------
 code      | character varying(9)   | not null
 name      | character varying(200) | not null

spending_item表中有100米行,organisation表中有大约10,000行。

我想要创建的物化视图如下 - 基本上它是每月的总支出和总项目数,按演示代码和组织分组。

(我正在创建它,因为我需要像#34这样的查询;对于代码为0304%的组织,给我按月和组织的总支出"或者#34;对于组织来说代码030405,按月和exp_code给我总支出"。我的数据每月只更改一次,所以我认为物化视图对此有意义。)

      Materialized view "public.vw_spending_summary"
      Column       |          Type           | Modifiers
-------------------+-------------------------+-----------
 processing_date   | date                    |
 organsiation_id   | character varying(9)    |
 organisation_name | character varying(200)  |
 total_cost        | double precision        |
 total_items       | double precision        |
 presentation_name | character varying(1000) |
 presentation_code | character varying(15)   |

我用来创建物化视图的查询如下:

SELECT spending_item.processing_date,
spending_item.organisation_id,
organisation.name,
spending_item.presentation_code,
spending_item.presentation_name,
SUM(spending_item.total_items) AS items,
SUM(spending_item.actual_cost) AS cost
FROM organisation, spending_item
WHERE spending_item.organisation_id=organisation.code
GROUP BY spending_item.processing_date, spending_item.presentation_name,   
spending_item.presentation_code, spending_item.organisation_id, 
organisation.name;

查询已运行了很多个小时,但还没有完成。

这是EXPLAIN ANALYZE对限制性更强的查询的结果(如上所述,但添加了WHERE spending_item.organisation_id like '0101%'):

 GroupAggregate  (cost=2263051.70..2291072.45 rows=934025 width=86) (actual time=60890.505..61069.808 rows=180 loops=1)
   ->  Sort  (cost=2263051.70..2265386.76 rows=934025 width=86) (actual time=60890.497..60945.558 rows=397717 loops=1)
         Sort Key: spending_item.processing_date, spending_item.presentation_name, spending_item.presentation_code, spending_item.organisation_id, organisation.name
         Sort Method: external sort  Disk: 32240kB
         ->  Hash Join  (cost=23877.71..2125733.64 rows=934025 width=86) (actual time=180.302..42251.826 rows=397717 loops=1)
               Hash Cond: ((spending_item.organisation_id)::text = (organisation.code)::text)
               ->  Bitmap Heap Scan on spending_item  (cost=23276.92..2109954.94 rows=934025 width=68) (actual time=178.521..41743.141 rows=397717 loops=1)
                     Filter: ((organisation_id)::text ~~ '0201%'::text)
                     ->  Bitmap Index Scan on spending_item_organisation_id_varchar_pattern_ops_idx  (cost=0.00..23043.41 rows=924684 width=0) (actual time=136.077..136.077 rows=397717 loops=1)
                           Index Cond: (((organisation_id)::text ~>=~ '0201'::text) AND ((organisation_id)::text ~<~ '0202'::text))
               ->  Hash  (cost=558.13..558.13 rows=3413 width=27) (actual time=1.774..1.774 rows=3413 loops=1)
                     Buckets: 1024  Batches: 1  Memory Usage: 203kB
                     ->  Seq Scan on organisation  (cost=0.00..558.13 rows=3413 width=27) (actual time=0.004..0.991 rows=3413 loops=1)
 Total runtime: 61089.664 ms

我很感激有关加快这项工作的任何建议。我已经将maintenance_work_memshared_buffers等设置得很高,所以我不认为我可以在settings front上做很多事情。

或者,对于我想要运行的两种类型的查询,拥有两个不同的物化视图会更有意义吗?

如果我能提供任何其他信息,请告诉我。

0 个答案:

没有答案