Received: from maia.hub.org (maia-3.hub.org [200.46.204.243]) by mail.postgresql.org (Postfix) with ESMTP id 2DE191337FE6 for ; Wed, 15 Sep 2010 03:19:42 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.243]) (amavisd-maia, port 10024) with ESMTP id 92311-02 for ; Wed, 15 Sep 2010 06:19:34 +0000 (UTC) X-Greylist: delayed 00:05:12.962875 by SQLgrey-1.7.6 Received: from mailout.thl.fi (mailout.thl.fi [193.167.195.59]) by mail.postgresql.org (Postfix) with ESMTP id F34F21337F85 for ; Wed, 15 Sep 2010 03:19:03 -0300 (ADT) Received: from mailout (localhost.localdomain [127.0.0.1]) by mailout.thl.fi (8.13.1/8.13.1) with SMTP id o8F6Dn1w017089 for ; Wed, 15 Sep 2010 09:13:49 +0300 Received: from 172.24.32.92 (172.24.32.92) by mailout (F-Secure/fsigk_smtp/580/mailout); Wed, 15 Sep 2010 09:13:49 +0200 (EET) X-Virus-Status: clean(F-Secure/fsigk_smtp/580/mailout) Received: from exhub1.stakes.fi (exhub1.stakes.fi [10.10.3.203]) by mail-hub.thl.fi (8.13.8/8.13.8) with ESMTP id o8F6Dnpm013927 for ; Wed, 15 Sep 2010 09:13:49 +0300 Received: from [172.24.70.235] (172.24.70.235) by exhub1.stakes.fi (10.10.3.203) with Microsoft SMTP Server id 8.1.375.2; Wed, 15 Sep 2010 09:13:48 +0300 Message-ID: <4C906706.40108@thl.fi> Date: Wed, 15 Sep 2010 09:26:14 +0300 From: =?ISO-8859-1?Q?Anssi_K=E4=E4ri=E4inen?= User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.12) Gecko/20100826 Thunderbird/3.0.7 MIME-Version: 1.0 To: Subject: Performance problem with joined aggregate query Content-Type: text/plain; charset="ISO-8859-1"; format=flowed Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by mail-hub.thl.fi id o8F6Dnpm013927 X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-1.91 tagged_above=-10 required=5 tests=BAYES_00=-1.9, T_RP_MATCHES_RCVD=-0.01 X-Spam-Level: X-Archive-Number: 201009/90 X-Sequence-Number: 40293 Hello all, I am trying to use aggregate queries in views, and when joining these=20 views to other tables, I get seq scan in the view, even if index scan would be clearly=20 better. The views I am using in my Db are actually long pivot queries, but the following=20 simple test case is enough to show the problem. I will first show the table definitions, then the performance problem I=20 am having. create table test1 ( id serial primary key not null, other_id integer unique not null ); create table test2 ( id integer not null references test1(id), type integer, value text ); create index test2_idx on test2(id); insert into test1 select g, g+10000 from (select generate_series(1,=20 10000) as g) t; insert into test2 select g, g%3, 'testval'||g from (select=20 generate_series(1, 10000) as g) t; insert into test2 select g, (g+1)%3, 'testval'||g from (select=20 generate_series(1, 10000) as g) t; insert into test2 select g, (g+2)%3, 'testval'||g from (select=20 generate_series(1, 10000) as g) t; Now, the following query is fast: select * from test1 inner join (select array_agg(value), id from test2 group by id) t on test1.id =3D t.id where test1.id =3D 1; (0.6ms) But the following query is slow (seqscan on test2): select * from test1 inner join (select array_agg(value), id from test2 group by id) t on test1.id =3D t.id where test1.other_id =3D 1= 0001; (45ms) The same problem can be seen when running: select * from test1 inner join (select array_agg(value), id from test2 group by id) t on test1.id =3D t.id where test1.id in (1, 2); (40ms runtime) Fetching directly from test2 with id is fast: select array_agg(value), id from test2 where test2.id in (1, 2) group by id; If I set enable_seqscan to off, then I get fast results: select * from test1 inner join (select array_agg(value), id from test2 group by id) t on test1.id =3D t.id where test1.other_id in=20 (10001, 10002); (0.6ms) Or slow results, if the fetched rows happen to be in the end of the index= : select * from test1 inner join (select array_agg(value), id from test2 group by id) t on test1.id =3D t.id where test1.other_id =3D 2= 0000; (40ms) Explain analyzes of the problematic query: With enable_seqscan: explain analyze select * from test1 inner join (select array_agg(value), = id from test2 group by id) t on test1.id =3D t.id where test1.other_id =3D 1= 0001; Hash Join (cost=3D627.48..890.48 rows=3D50 width=3D44) (actual=20 time=3D91.575..108.085 rows=3D1 loops=3D1) Hash Cond: (test2.id =3D test1.id) -> HashAggregate (cost=3D627.00..752.00 rows=3D10000 width=3D15) (a= ctual=20 time=3D82.663..98.281 rows=3D10000 loops=3D1) -> Seq Scan on test2 (cost=3D0.00..477.00 rows=3D30000 width=3D= 15)=20 (actual time=3D0.009..30.650 rows=3D30000 loops=3D1) -> Hash (cost=3D0.47..0.47 rows=3D1 width=3D8) (actual time=3D0.026= ..0.026=20 rows=3D1 loops=3D1) -> Index Scan using test1_other_id_key on test1 =20 (cost=3D0.00..0.47 rows=3D1 width=3D8) (actual time=3D0.018..0.021 rows=3D= 1 loops=3D1) Index Cond: (other_id =3D 10001) Total runtime: 109.686 ms Without enable_seqscan: explain analyze select * from test1 inner join (select array_agg(value), = id from test2 group by id) t on test1.id =3D t.id where test1.other_id =3D 1= 0001; Merge Join (cost=3D0.48..895.91 rows=3D50 width=3D44) (actual=20 time=3D0.066..0.085 rows=3D1 loops=3D1) Merge Cond: (test2.id =3D test1.id) -> GroupAggregate (cost=3D0.00..769.56 rows=3D10000 width=3D15) (ac= tual=20 time=3D0.040..0.054 rows=3D2 loops=3D1) -> Index Scan using test2_idx on test2 (cost=3D0.00..494.56=20 rows=3D30000 width=3D15) (actual time=3D0.017..0.030 rows=3D7 loops=3D1) -> Sort (cost=3D0.48..0.48 rows=3D1 width=3D8) (actual time=3D0.020= ..0.022=20 rows=3D1 loops=3D1) Sort Key: test1.id Sort Method: quicksort Memory: 17kB -> Index Scan using test1_other_id_key on test1 =20 (cost=3D0.00..0.47 rows=3D1 width=3D8) (actual time=3D0.010..0.012 rows=3D= 1 loops=3D1) Index Cond: (other_id =3D 10001) - Anssi K=E4=E4ri=E4inen