Received: from localhost (maia-1.hub.org [200.46.204.191]) by postgresql.org (Postfix) with ESMTP id 0BC739FA4B4 for ; Sun, 22 Jul 2007 06:07:13 -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 77955-02 for ; Sun, 22 Jul 2007 06:07:10 -0300 (ADT) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.5 Received: from ciao.gmane.org (main.gmane.org [80.91.229.2]) by postgresql.org (Postfix) with ESMTP id 1C26D9FA443 for ; Sun, 22 Jul 2007 06:07:10 -0300 (ADT) Received: from list by ciao.gmane.org with local (Exim 4.43) id 1ICXP5-0006ij-Bu for pgsql-sql@postgresql.org; Sun, 22 Jul 2007 11:07:03 +0200 Received: from 2109ds1-taa.0.fullrate.dk ([90.184.133.88]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sun, 22 Jul 2007 11:07:03 +0200 Received: from nis by 2109ds1-taa.0.fullrate.dk with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sun, 22 Jul 2007 11:07:03 +0200 X-Injected-Via-Gmane: http://gmane.org/ To: pgsql-sql@postgresql.org From: =?UTF-8?B?TmlzIErDuHJnZW5zZW4=?= Subject: Re: The nested view from hell - Restricting a subquerry Date: Sun, 22 Jul 2007 11:06:45 +0200 Lines: 59 Message-ID: References: <46A2CABF.3080108@obviously.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Complaints-To: usenet@sea.gmane.org X-Gmane-NNTP-Posting-Host: 2109ds1-taa.0.fullrate.dk User-Agent: Thunderbird 1.5.0.12 (Windows/20070509) In-Reply-To: <46A2CABF.3080108@obviously.com> X-Virus-Scanned: Maia Mailguard 1.0.1 X-Archive-Number: 200707/124 X-Sequence-Number: 28859 Bryce Nesbitt skrev: > I've got a legacy app with a hefty performance problem. The basic > problem is stupid design. It takes 10-15 seconds of CPU time to look up > an invoice. > Basically it's trying to mash up extra columns on an otherwise simple > query, and those extra columns are subtotals. Simplified (this looks > best in a fixed width font): > > SELECT max(order_view.order_id),max(order_view.invoice_id) > ,sum(order_view.mileage) > FROM (SELECT order_id,invoice_id, 0 as miles FROM eg_order > UNION > SELECT order_id,0 , miles FROM eg_order_line) > order_view GROUP BY order_view.order_id; > > A select by order_id is fast. The problem is the application uses > "select * from view where invoice_id=x", and the second part of the > UNION returns all possible rows in the database. These get filtered out > later, but at considerable performance hit. Just for the record, I believe your simplified example should look like this (changed "max(order_id)" to "order_id" in outer select , changed "miles" to "mileage"): SELECT order_id, max(order_view.invoice_id), sum(order_view.mileage) FROM (SELECT order_id,invoice_id, 0 as mileage FROM eg_order UNION SELECT order_id, 0, mileage FROM eg_order_line) order_view GROUP BY order_view.order_id; It is pretty clear that the problem comes from joining on the result of an aggregate. PG apparently is not smart enough to recognize that the result of a max must be one of the values of the column (meaning that it can use an index) It is not clear whether there is a FK relation between eg_order and eg_order_line and what the PK of eg_order is. If there is a FK, you can do something along the lines of SELECT order_id, invoice_id COALESCE(sum(mileage),0) as mileage FROM eg_order LEFT JOIN eg_order_line USING order_id GROUP BY order_id, invoice_id If there can be more than one invoice_id per order_id, you might need to add HAVING invoice_id = (SELECT max(invoice_id) FROM eg_order eo2 WHERE eg_order.order_id = eo2.order_id) or similar. Hope this helps, Nis