X-Original-To: pgsql-performance-postgresql.org@localhost.postgresql.org Received: from localhost (av.hub.org [200.46.204.144]) by postgresql.org (Postfix) with ESMTP id 04E289DCC16 for ; Wed, 22 Feb 2006 05:43:40 -0400 (AST) Received: from postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 82445-03 for ; Wed, 22 Feb 2006 05:43:42 -0400 (AST) Received: from svr4.postgresql.org (svr4.postgresql.org [66.98.251.159]) by postgresql.org (Postfix) with ESMTP id CD3079DCC24 for ; Wed, 22 Feb 2006 05:43:38 -0400 (AST) Received: from pih-relay06.plus.net (pih-relay06.plus.net [212.159.14.133]) by svr4.postgresql.org (Postfix) with ESMTP id 2FEDF5AF097 for ; Wed, 22 Feb 2006 09:43:41 +0000 (GMT) Received: from [213.162.97.75] (helo=mail.metronet.co.uk) by pih-relay06.plus.net with esmtp (Exim) id 1FBqWz-0000Zu-7X; Wed, 22 Feb 2006 09:43:33 +0000 Received: from mainbox.archonet.com (84-51-143-99.archon037.adsl.metronet.co.uk [84.51.143.99]) by smtp.metronet.co.uk (MetroNet Mail) with ESMTP id 68CCE414B19; Wed, 22 Feb 2006 09:38:05 +0000 (GMT) Received: from [192.168.1.17] (client17.office.archonet.com [192.168.1.17]) by mainbox.archonet.com (Postfix) with ESMTP id F406C15EA6; Wed, 22 Feb 2006 09:38:04 +0000 (GMT) Message-ID: <43FC30FC.3080800@archonet.com> Date: Wed, 22 Feb 2006 09:38:04 +0000 From: Richard Huxton User-Agent: Thunderbird 1.5 (X11/20051201) MIME-Version: 1.0 To: George Woodring Cc: pgsql-performance@postgresql.org Subject: Re: Help with nested loop left join performance References: <1B1B254441DB31448BD34C5BD73B0B8B28FBF6@PHOENIX.istructure.com> In-Reply-To: <1B1B254441DB31448BD34C5BD73B0B8B28FBF6@PHOENIX.istructure.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, score=0.118 required=5 tests=[AWL=0.118] X-Spam-Score: 0.118 X-Spam-Level: X-Archive-Number: 200602/336 X-Sequence-Number: 17322 George Woodring wrote: > > explain analyze SELECT column1, column2, column3, column4, column5, > column6, column7, column8 FROM (SELECT CASE status WHEN 0 THEN 0 WHEN 1 > THEN 1 ELSE -1 END AS column1, mac AS column2, account AS column3, > number || ' ' || address AS column4, 'qmod' || '.' || 'dmod' AS column5, > node AS column6, grid AS column7, boxtype AS column8, number, address > FROM settop_billing LEFT OUTER JOIN (dhct JOIN dhct_davic USING(mac)) > USING (mac) WHERE region='GTown1E' AND node='1E012' ) AS foo; Ach y fi! Let's format that a bit better, eh? explain analyze SELECT column1, column2, column3, column4, column5,column6, column7, column8 FROM ( SELECT CASE status WHEN 0 THEN 0 WHEN 1 THEN 1 ELSE -1 END AS column1, mac AS column2, account AS column3, number || ' ' || address AS column4, 'qmod' || '.' || 'dmod' AS column5, node AS column6, grid AS column7, boxtype AS column8, number, address FROM settop_billing LEFT OUTER JOIN (dhct JOIN dhct_davic USING(mac)) USING (mac) WHERE region='GTown1E' AND node='1E012' ) AS foo; Now we can see what's happening. Well, looking at it laid out like that, I'm suspcious of the (dhct JOIN dhct_davic) on the outside of an outer join. Looking at your explain we do indeed have two sequential scans over the tables in question - the big one being dhct... > -> Append (cost=0.00..8881.11 rows=384912 width=8) > (actual time=0.023..10914.365 rows=384900 loops=1) > -> Seq Scan on dhct_davic (cost=0.00..0.00 rows=1 > width=8) (actual time=0.002..0.002 rows=0 loops=1) > -> Seq Scan on probe_dhct_davic dhct_davic > (cost=0.00..8881.11 rows=384911 width=8) (actual time=0.018..10505.255 > rows=384900 loops=1) > -> Hash (cost=12154.13..12154.13 rows=410613 width=6) > (actual time=923.433..923.433 rows=0 loops=1) > -> Seq Scan on dhct (cost=0.00..12154.13 > rows=410613 width=6) (actual time=0.019..534.641 rows=409576 loops=1) With 7.4 I seem to remember that explicit JOINs force the evaluation order, but I'm not if even later versions will rewrite your query. It's too early in the morning for me to figure out if it's safe in all cases. Anyway, for your purposes, I'd say something more like: FROM settop_billing LEFT JOIN dhct LEFT JOIN dhct_davic That should let the planner do the joins in a more reasonable order. -- Richard Huxton Archonet Ltd