Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.80) (envelope-from ) id 1YjETE-0002vx-Ff for pgsql-sql@arkaria.postgresql.org; Fri, 17 Apr 2015 22:10:44 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.80) (envelope-from ) id 1YjETD-0001rf-Ts for pgsql-sql@arkaria.postgresql.org; Fri, 17 Apr 2015 22:10:43 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1YjETC-0001pc-Dg for pgsql-sql@postgresql.org; Fri, 17 Apr 2015 22:10:42 +0000 Received: from post.visena.com ([46.226.10.50]) by magus.postgresql.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.80) (envelope-from ) id 1YjET8-0005ug-0B for pgsql-sql@postgresql.org; Fri, 17 Apr 2015 22:10:41 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=visena.com; s=20141101.wh; h=Content-Type:MIME-Version:Subject:Message-ID:To:From:Date; bh=BfzNANLMeGwoXiJm8SAV3VF16Z+C+R6cfsPNyqXgzIE=; b=Sd0fTcSD1yfJ4fga8c8hVtQLMhnng/7rHeK5xi8wEbmR12uLNws4ijR7WsD5MA/mSmSMX6tEbtlI8MNMIGhSdT+ysDuYoOp/B26CCte6maifCviechDhJrjQ9GESmb/B5XyWuw4W9I+BD9vXp6OxyYNdaSgGIilggQN+Mxmn4oc=; Received: from [10.0.1.10] (helo=tc7-visena.wh.internal.visena.com) by post.visena.com with esmtp (Exim 4.82) (envelope-from ) id 1YjET4-0001B1-Pr for pgsql-sql@postgresql.org; Sat, 18 Apr 2015 00:10:37 +0200 Received: from localhost ([127.0.0.1] helo=tc7-visena.wh.internal.visena.com) by tc7-visena.wh.internal.visena.com with esmtp (Exim 4.82) (envelope-from ) id 1YjET4-000282-U0 for pgsql-sql@postgresql.org; Sat, 18 Apr 2015 00:10:34 +0200 Date: Sat, 18 Apr 2015 00:10:34 +0200 (CEST) From: Andreas Joseph Krogh To: pgsql-sql@postgresql.org Message-ID: Subject: Best way to aggregate sum for each month MIME-Version: 1.0 X-Mailer: Visena Mail 1.9.0-SNAPSHOT X-Spam-Score: -1.0 X-Spam-Report: SpamAssasin (score=-1.0, required 5.0 ALL_TRUSTED=-1, HTML_MESSAGE=0.001) X-Pg-Spam-Score: -2.0 (--) Content-Type: multipart/related; boundary="----=_Part_41_1233651981.1429308634830" List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-sql Precedence: bulk Sender: pgsql-sql-owner@postgresql.org ------=_Part_40_1427175144.1429308634830 Content-Type: multipart/related; boundary="----=_Part_41_1233651981.1429308634830" ------=_Part_41_1233651981.1429308634830 Content-Type: multipart/alternative; boundary="----=_Part_42_856715267.1429308634851" ------=_Part_42_856715267.1429308634851 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hi all. =C2=A0 I'm using PG-9.4. =C2=A0 I'm having a table, activity_log, w= hich holds=20 activities with duration for a given date. I'm trying to sum the duration f= or=20 each month in a given year and am currently doing it like this: =C2=A0 sele= ct=20 q.start_date ,sum(log.duration) / (3600 * 1000)::NUMERIC as total_duration = FROM=20 (SELECT cast(generate_series('2014-01-01' :: DATE, '2014-12-01' :: DATE, '1= =20 month') AS DATE) as start_date) AS q LEFT OUTER JOIN activity_log log ON=20 date_trunc('month', log.start_date::timestamp without time zone) =3D q.star= t_date=20 GROUP BYq.start_date ORDER BY q.start_date ; I have the current index defin= ed: =C2=A0 create indexactivity_start_month ON activity_log(date_trunc('month',=20 start_date::timestamp without time zone)); =C2=A0 Here's the explain plan: = =C2=A0=20 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=20 QUERY PLAN =20 ---------------------------------------------------------------------------= ---------------------------------------------------------------------------= ---------------------------------------------------------------------------= -------------- =C2=A0GroupAggregate=C2=A0 (cost=3D65.27..91102.17 rows=3D200 width=3D12) = (actual=20 time=3D179.983..344.517 rows=3D12 loops=3D1) =C2=A0=C2=A0 Group Key: ((generate_series(('2014-01-01'::date)::timestamp = with time=20 zone, ('2014-12-01'::date)::timestamp with time zone, '1 mon'::interval))::= date) =C2=A0=C2=A0 ->=C2=A0 Merge Left Join=C2=A0 (cost=3D65.27..82950.79 rows= =3D1629675 width=3D12) (actual=20 time=3D163.894..310.011 rows=3D143551 loops=3D1) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Merge Cond: (((generate_s= eries(('2014-01-01'::date)::timestamp with=20 time zone, ('2014-12-01'::date)::timestamp with time zone, '1=20 mon'::interval))::date) =3D date_trunc('month'::text, (log.start_date)::tim= estamp=20 without time zone)) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ->=C2=A0 Sort=C2=A0 (cost= =3D64.84..67.34 rows=3D1000 width=3D4) (actual=20 time=3D0.045..0.052 rows=3D12 loops=3D1) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0 Sort Key: ((generate_series(('2014-01-01'::date)::timestamp=20 with time zone, ('2014-12-01'::date)::timestamp with time zone, '1=20 mon'::interval))::date) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0 Sort Method: quicksort=C2=A0 Memory: 25kB =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0 ->=C2=A0 Result=C2=A0 (cost=3D0.00..5.01 rows=3D1000 width=3D0= ) (actual=20 time=3D0.017..0.031 rows=3D12 loops=3D1) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ->=C2=A0 Materialize=C2= =A0 (cost=3D0.42..51097.29 rows=3D325935 width=3D12) (actual=20 time=3D0.032..227.692 rows=3D323180 loops=3D1) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0 ->=C2=A0 Index Scan using activity_start_month on activity_log= log=C2=A0=20 (cost=3D0.42..50282.45 rows=3D325935 width=3D12) (actual time=3D0.029..185.= 746=20 rows=3D323180 loops=3D1) =C2=A0Planning time: 0.201 ms =C2=A0Execution time: 344.645 ms (12 rows) =C2=A0 =C2=A0 Are there any ways to improve this? =C2=A0 Thanks.= =C2=A0 -- Andreas=20 Joseph Krogh CTO / Partner - Visena AS Mobile: +47 909 56 963 andreas@visen= a.com www.visena.com =20 ------=_Part_42_856715267.1429308634851 Content-Type: text/html;charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi all.
=C2=A0
I'm using PG-9.4.
=C2=A0
I'm having a table, activity_log, which holds activities with duration= for a given date.
I'm trying to sum the duration for each month in a given year and am c= urrently doing it like this:
=C2=A0
select
    q.star=
t_date
    , sum(log.duration) / (3600 * 1000<=
/span>)::NUMERIC =
as total_duration
FROM
    (SELECT <=
span style=3D"color: rgb(0, 0, 128); font-style: italic;">cast(generate_series('2014-01-01' :: DATE, '2014-12-01' :: DATE, '1 month') AS DATE) as start_date) AS q
    LEFT OUTER JO=
IN activity_log log ON date_trunc(<=
span style=3D"color: rgb(0, 128, 0); font-weight: bold;">'month', log.start_date::timestamp without ti=
me zone) =3D q.start_date
GROUP BY q=
.start_date
ORDER BY q=
.start_date
;

I have the current index defined:
=C2=A0
create index activity_start_month ON activity_log(date_trunc('month', start_date::timestamp without time zone));

=C2=A0
Here's the explain plan:
=C2=A0
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 QUERY PLAN
---------------------------------------------------------------------------= ---------------------------------------------------------------------------= ---------------------------------------------------------------------------= --------------
=C2=A0GroupAggregate=C2=A0 (cost=3D65.27..91102.17 rows=3D200 width=3D12) (= actual time=3D179.983..344.517 rows=3D12 loops=3D1)
=C2=A0=C2=A0 Group Key: ((generate_series(('2014-01-01'::date)::timestamp w= ith time zone, ('2014-12-01'::date)::timestamp with time zone, '1 mon'::int= erval))::date)
=C2=A0=C2=A0 ->=C2=A0 Merge Left Join=C2=A0 (cost=3D65.27..82950.79 rows= =3D1629675 width=3D12) (actual time=3D163.894..310.011 rows=3D143551 loops= =3D1)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Merge Cond: (((generate_se= ries(('2014-01-01'::date)::timestamp with time zone, ('2014-12-01'::date)::= timestamp with time zone, '1 mon'::interval))::date) =3D date_trunc('month'= ::text, (log.start_date)::timestamp without time zone))
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ->=C2=A0 Sort=C2=A0 (co= st=3D64.84..67.34 rows=3D1000 width=3D4) (actual time=3D0.045..0.052 rows= =3D12 loops=3D1)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 Sort Key: ((generate_series(('2014-01-01'::date)::timestamp with = time zone, ('2014-12-01'::date)::timestamp with time zone, '1 mon'::interva= l))::date)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 Sort Method: quicksort=C2=A0 Memory: 25kB
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 ->=C2=A0 Result=C2=A0 (cost=3D0.00..5.01 rows=3D1000 width=3D0= ) (actual time=3D0.017..0.031 rows=3D12 loops=3D1)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ->=C2=A0 Materialize=C2= =A0 (cost=3D0.42..51097.29 rows=3D325935 width=3D12) (actual time=3D0.032..= 227.692 rows=3D323180 loops=3D1)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 ->=C2=A0 Index Scan using activity_start_month on activity_log= log=C2=A0 (cost=3D0.42..50282.45 rows=3D325935 width=3D12) (actual time=3D= 0.029..185.746 rows=3D323180 loops=3D1)
=C2=A0Planning time: 0.201 ms
=C2=A0Execution time: 344.645 ms
(12 rows)
=C2=A0
=C2=A0
Are there any ways to improve this?
=C2=A0
Thanks.
=C2=A0
--
Andrea= s Joseph Krogh
CTO / Partner<= /span> - Visena AS
Mobile: +47 90= 9 56 963
=3D""
------=_Part_42_856715267.1429308634851-- ------=_Part_41_1233651981.1429308634830 Content-Type: image/png Content-Transfer-Encoding: base64 Content-Disposition: inline Content-ID: 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 ------=_Part_41_1233651981.1429308634830-- ------=_Part_40_1427175144.1429308634830--