Received: from localhost (maia-1.hub.org [200.46.204.191]) by postgresql.org (Postfix) with ESMTP id 4F9F19FB4B9 for ; Fri, 22 Jun 2007 19:24:12 -0300 (ADT) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.191]) (amavisd-maia, port 10024) with ESMTP id 41099-08 for ; Fri, 22 Jun 2007 19:24:08 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey-1.7.5 Received: from exchange.g2switchworks.com (mail.g2switchworks.com [38.98.183.40]) by postgresql.org (Postfix) with ESMTP id 0FA1A9FB4BD for ; Fri, 22 Jun 2007 19:24:08 -0300 (ADT) Received: from [10.10.1.37] ([10.10.1.37]) by exchange.g2switchworks.com with Microsoft SMTPSVC(6.0.3790.1830); Fri, 22 Jun 2007 17:24:07 -0500 Message-ID: <467C4C07.1090700@g2switchworks.com> Date: Fri, 22 Jun 2007 17:24:07 -0500 From: Scott Marlowe User-Agent: Thunderbird 1.5.0.4 (X11/20060516) MIME-Version: 1.0 To: Tom Tamulewicz CC: grzm@seespotcode.net, pgsql-performance@postgresql.org Subject: Re: Slow join query References: In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 22 Jun 2007 22:24:07.0880 (UTC) FILETIME=[0C9EE480:01C7B51C] X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0.224 tagged_above=0 required=5 tests=AWL=0.223, BAYES_50=0.001 X-Spam-Level: X-Archive-Number: 200706/553 X-Sequence-Number: 25586 Tom Tamulewicz wrote: > > > > ------------------------------------------------------------------------ > > SELECT p.party_id, p.first_name, p.last_name, pli.address1, > pli.city, pli.state FROM customer as p JOIN address as pli ON ( > p.party_id = pli.party_id ) WHERE ( p.void_flag IS NULL OR > p.void_flag = false ) AND (first_name like 'B%') AND (last_name > like 'S%') AND (pli.state like 'M%') AND (pli.city like 'AL%') > ORDER BY last_name, first_name LIMIT 51 > > > QUERY PLAN > --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- > Limit (cost=0.00..96.48 rows=1 width=2450) (actual > time=13459.814..13459.814 rows=0 loops=1) > -> Nested Loop (cost=0.00..96.48 rows=1 width=2450) (actual > time=13459.804..13459.804 rows=0 loops=1) > -> Index Scan using idx_last_name on customer p > (cost=0.00..50.22 rows=1 width=1209) (actual > time=57.812..13048.524 rows=2474 loops=1) > Index Cond: (((last_name)::text >= 'S'::character > varying) AND ((last_name)::text < 'T'::character varying) AND > ((first_name)::text >= 'B'::character varying) AND > ((first_name)::text < 'C'::character varying)) > Filter: (((void_flag IS NULL) OR (void_flag = > false)) AND ((first_name)::text ~~ 'B%'::text) AND > ((last_name)::text ~~ 'S%'::text)) > -> Index Scan using address_pkey on address pli > (cost=0.00..46.23 rows=1 width=1257) (actual time=0.149..0.149 > rows=0 loops=2474) > Index Cond: (("outer".party_id = pli.party_id)) > Filter: (((state)::text ~~ 'M%'::text) AND > ((city)::text ~~ 'AL%'::text)) > Total runtime: 13460.292 ms > The problem here is this bit: -> Index Scan using idx_last_name on customer p (cost=0.00..50.22 rows=1 width=1209) (actual time=57.812..13048.524 rows=2474 loops=1) Index Cond: (((last_name)::text >= 'S'::character varying) AND ((last_name)::text < 'T'::character varying) AND ((first_name)::text >= 'B'::character varying) AND ((first_name)::text < 'C'::character varying)) Filter: (((void_flag IS NULL) OR (void_flag = false)) AND ((first_name)::text ~~ 'B%'::text) AND ((last_name)::text ~~ 'S%'::text)) Note that you're getting back 2474 rows, but the planner expects 1. Not the actual time going from 57 to 13048, it's spending all it's time looking up each tuple in the index, then in the table. Using a seq scan would be much faster. Have you analyzed this table? If so, you might need to up the stats target on last_name and see if that helps.