Received: from localhost (unknown [200.46.204.183]) by developer.postgresql.org (Postfix) with ESMTP id 13A072E0076 for ; Sun, 27 Apr 2008 23:13:39 -0300 (ADT) Received: from developer.postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 55457-10 for ; Sun, 27 Apr 2008 23:13:36 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey-1.7.5 Received: from dc.baikal.ru (dc.baikal.ru [212.176.3.237]) by developer.postgresql.org (Postfix) with ESMTP id DC41A2E0072 for ; Sun, 27 Apr 2008 23:13:35 -0300 (ADT) Received: from it319k5.dc-local (it319k5.dc-local [10.0.4.75]) (authenticated bits=0) by dc.baikal.ru (8.13.8/8.13.8) with ESMTP id m3S2DVIQ007802 for ; Mon, 28 Apr 2008 11:13:32 +0900 Message-ID: <481532CC.3080502@dc.baikal.ru> Date: Mon, 28 Apr 2008 11:13:32 +0900 From: Vlad Arkhipov User-Agent: Thunderbird 2.0.0.0 (X11/20070326) MIME-Version: 1.0 To: pgsql-performance@postgresql.org Subject: Simple JOIN problem Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: ClamAV version 0.93, clamav-milter version 0.93 on dc.baikal.ru X-Virus-Status: Clean X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0 tagged_above=0 required=5 tests=AWL=0.000 X-Spam-Level: X-Archive-Number: 200804/385 X-Sequence-Number: 29878 I run on PostgreSQL 8.3, default settings (also tried to change random_page_cost close to 1). What need I change to make the second query run as fast as the first? Set enable_hashjoin to off solves this problem, but it's not the way I can use. Statistics for all columns is on the level 1000. explain analyze select * from c join i on i.c_id = c.id where c.d between '2007-02-01' and '2007-02-06' Nested Loop (cost=0.00..25066.24 rows=4771 width=28) (actual time=0.129..52.499 rows=5215 loops=1) -> Index Scan using c_d_idx on c (cost=0.00..86.77 rows=2368 width=12) (actual time=0.091..4.623 rows=2455 loops=1) Index Cond: ((d >= '2007-02-01'::date) AND (d <= '2007-02-06'::date)) -> Index Scan using i_c_id_idx on i (cost=0.00..10.51 rows=3 width=16) (actual time=0.006..0.010 rows=2 loops=2455) Index Cond: (i.c_id = c.id) Total runtime: 59.501 ms explain analyze select * from c join i on i.c_id = c.id where c.d between '2007-02-01' and '2007-02-07' Hash Join (cost=143.53..27980.95 rows=6021 width=28) (actual time=612.282..4162.321 rows=6497 loops=1) Hash Cond: (i.c_id = c.id) -> Seq Scan on i (cost=0.00..19760.59 rows=1282659 width=16) (actual time=0.073..2043.658 rows=1282659 loops=1) -> Hash (cost=106.18..106.18 rows=2988 width=12) (actual time=11.635..11.635 rows=3064 loops=1) -> Index Scan using c_d_idx on c (cost=0.00..106.18 rows=2988 width=12) (actual time=0.100..6.055 rows=3064 loops=1) Index Cond: ((d >= '2007-02-01'::date) AND (d <= '2007-02-07'::date)) Total runtime: 4171.049 ms CREATE TABLE c ( id bigint NOT NULL, d date, CONSTRAINT c_id_pk PRIMARY KEY (id) ); CREATE INDEX c_d_idx ON c USING btree (d); CREATE TABLE i ( val bigint, c_id bigint, CONSTRAINT i_c_id_fk FOREIGN KEY (c_id) REFERENCES c (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION ); CREATE INDEX i_c_id_idx ON i USING btree (c_id);