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 14F449DCA0D for ; Wed, 8 Feb 2006 09:54:56 -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 52123-01 for ; Wed, 8 Feb 2006 09:54:59 -0400 (AST) X-Greylist: from auto-whitelisted by SQLgrey- Received: from mail.suntradingllc.com (mail.suntradingllc.com [66.227.78.98]) by postgresql.org (Postfix) with ESMTP id 5809D9DCA6E for ; Wed, 8 Feb 2006 09:54:52 -0400 (AST) Received: (qmail 28612 invoked by uid 89); 8 Feb 2006 13:54:54 -0000 Received: by simscan 1.1.0 ppid: 28604, pid: 28607, t: 0.9201s scanners: attach: 1.1.0 clamav: 0.85.1/m:34/d:1166 spam: 3.0.4 Received: from unknown (HELO ?172.20.34.18?) (jake@suntradingllc.com@172.20.34.18) by 0 with SMTP; 8 Feb 2006 13:54:53 -0000 Subject: optimizing away join when querying view From: Jacob Costello To: pgsql-performance@postgresql.org Content-Type: text/plain Organization: Sun Trading, LLC Date: Wed, 08 Feb 2006 07:54:51 -0600 Message-Id: <1139406891.11389.60.camel@localhost.localdomain> Mime-Version: 1.0 X-Mailer: Evolution 2.2.3 (2.2.3-2.fc4) Content-Transfer-Encoding: 7bit X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, score=0.12 required=5 tests=[AWL=0.120] X-Spam-Score: 0.12 X-Spam-Level: X-Archive-Number: 200602/66 X-Sequence-Number: 17052 Postgres doesn't seem to optimize away unnecessary joins in a view definition when the view is queried in such a way that the join need not be executed. In the example below, I define two tables, foo and bar, with a foreign key on bar referencing foo, and a view on the natural join of the tables. The tables are defined so that the relationship from bar to foo is allowed to be many to one, with the column of bar referencing foo (column a) set NOT NULL, so that there must be exactly one foo record for every bar record. I then EXPLAIN selecting the "b" column from bar, through the view and from bar directly. The tables have been ANALYZEd but have no data. EXPLAIN shows the join actually occurring when selecting b from the view quux. If I understand correctly (maybe I don't), this is guaranteed to be exactly the same as the selecting b directly from the bar table. The practical import of this comes into play when views are provided to simplify queries for end users, and those views use joins to include related data. If the user enters a query that is equivalent to a query on a base table, why should the query pay a performance penalty ? table foo: Column | Type | Modifiers --------+---------+----------- a | integer | not null Indexes: "foo_pkey" PRIMARY KEY, btree (a) table bar: Column | Type | Modifiers --------+---------+----------- a | integer | not null b | integer | Foreign-key constraints: "bar_a_fkey" FOREIGN KEY (a) REFERENCES foo(a) view quux: Column | Type | Modifiers --------+---------+----------- a | integer | b | integer | View definition: SELECT bar.a, bar.b FROM bar NATURAL JOIN foo EXPLAINed Queries: explain select b from bar; QUERY PLAN --------------------------------------------------- Seq Scan on bar (cost=0.00..1.00 rows=1 width=4) (1 row) explain select b from quux; QUERY PLAN -------------------------------------------------------------------------- Nested Loop (cost=0.00..5.84 rows=1 width=4) -> Seq Scan on bar (cost=0.00..1.00 rows=1 width=8) -> Index Scan using foo_pkey on foo (cost=0.00..4.82 rows=1 width=4) Index Cond: ("outer".a = foo.a) (4 rows) -- Jacob Costello Sun Trading, LLC