X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (av.hub.org [200.46.204.144]) by svr1.postgresql.org (Postfix) with ESMTP id 46153D9B0A for ; Fri, 30 Sep 2005 15:40:11 -0300 (ADT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 61424-01 for ; Fri, 30 Sep 2005 18:40:08 +0000 (GMT) Received: from qproxy.gmail.com (qproxy.gmail.com [72.14.204.203]) by svr1.postgresql.org (Postfix) with ESMTP id 0F118D9A84 for ; Fri, 30 Sep 2005 15:40:08 -0300 (ADT) Received: by qproxy.gmail.com with SMTP id f9so144780qba for ; Fri, 30 Sep 2005 11:40:09 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:reply-to:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=jJhrsS01iIjTdgUkeqBWrW785zINhwuhzXbI3zEVYeeXK+85o3mzlmdAXeu5SFnog/LLwt+KjaQxu2Xdj/2DX/+JhpM+jKfuZBOiEt3IDVDmDPaleupQqbYSmF8BZeP+2Iz0ckcsjzeM+KzlN5lSLeuG3zqO9Zfdu1GzrfQAEoc= Received: by 10.65.150.12 with SMTP id c12mr1076913qbo; Fri, 30 Sep 2005 11:40:09 -0700 (PDT) Received: by 10.65.53.19 with HTTP; Fri, 30 Sep 2005 11:40:09 -0700 (PDT) Message-ID: Date: Fri, 30 Sep 2005 13:40:09 -0500 From: Jaime Casanova Reply-To: Jaime Casanova To: "jan aerts (RI)" Subject: Re: combination of function to simple query makes query slow Cc: pgsql-sql@postgresql.org In-Reply-To: <84DA9D8AC9B05F4B889E7C70238CB45101FD6555@rie2ksrv1.ri.bbsrc.ac.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline References: <84DA9D8AC9B05F4B889E7C70238CB45101FD6555@rie2ksrv1.ri.bbsrc.ac.uk> X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, hits=0.714 required=5 tests=[AWL=0.690, RCVD_BY_IP=0.024] X-Spam-Level: X-Archive-Number: 200509/304 X-Sequence-Number: 22851 On 9/30/05, jan aerts (RI) wrote: > Hi, > > I'm having some problems in combining a function within a standard > query. > > I basically have two tables (see between hashes below): > * alias_table: objects can have different names (e.g. name1 is an alias > of name2, and name3 is an alias of name4) > * mapping_table: shows objects that 'lead to' other objects (e.g. the > object with name1 leads to the object with name5) > > I want to traverse the mapping_table in a transparent way: if a first > object leads to a second object, and that second object leads to a third > object, I want to list the first and the third objects. So from the > example table below: name6 leads to name2, which is an alias of name1, > which in its turn leads to name5. The result of my query should be: > name6 leads to name5. > > To accomplish this, I wrote a little function ('aliases_of'), as > described below between the hashes. > > The query > SELECT aliases_of(1); > returns: > aliases_of > ---------- > 1 > 2 > , which is the expected output. > > The query > SELECT * FROM mapping_table > WHERE object1_id IN ( SELECT aliases_of(2) ); > returns: > object1_id | object1_name | object2_id | object2_name > ----------------------------------------------------- > 1 | name1 | 5 | name5 > , which is the expected output, because it is equivalent to: > SELECT * FROM mapping_table > WHERE object1_id IN ( 1, 2 ); > > However, the query that would traverse the data: > SELECT m1.object1_id, m1.object1_name, m2.object2_id, m2.object2_name > FROM mapping_table m1, mapping_table m2 > WHERE m1.object2_id IN ( SELECT aliases_of(m2.object1_id) ); > just keeps on running, and never seems to stop. (I must say that that > table in effect contains about a million records.) > The expected output would have been: > object1_id | object1_name | object2_id | object2_name > ----------------------------------------------------- > 6 | name6 | 5 | name5 > > I also tried to following, which doesn't work either. > SELECT m1.object1_id, m1.object1_name, m2.object2_id, m2.object2_name > FROM mapping_table m1 JOIN mapping_table m2 ON ( m1.object2_id IN ( > SELECT aliases_of(m2.object1_id) ); > > Is there a way to speed up this query? I'd also have to be able to > traverse the mapping_table ever further, following a path of things that > 'lead to' other things. > > I hope I made myself clear a bit... > Any help appreciated. Many thanks, > jan. > > ################################################################ > (A) TABLE: alias_table > object1_id | object1_name | object2_id | object2_name > ----------------------------------------------------- > 1 | name1 | 2 | name2 > 3 | name3 | 4 | name4 > > (B) TABLE: mapping_table > object1_id | object1_name | object2_id | object2_name > ----------------------------------------------------- > 1 | name1 | 5 | name5 > 6 | name6 | 2 | name2 > > (C) FUNCTION: aliases_of > CREATE FUNCTION aliases_of(bigint) RETURNS SETOF bigint > AS 'SELECT $1 > UNION > SELECT object1_id FROM alias_table WHERE object2_id =3D $1 > UNION > SELECT object2_id FROM alias_table WHERE object1_id =3D $1 > ' > LANGUAGE SQL; > ################################################################ > > maybe you can show us an EXPLAIN of your select: EXPLAIN select_statement -- Atentamente, Jaime Casanova (DBA: DataBase Aniquilator ;)