Re: combination of function to simple query makes query slow - Mailing list pgsql-sql
From | jan aerts (RI) |
---|---|
Subject | Re: combination of function to simple query makes query slow |
Date | |
Msg-id | 84DA9D8AC9B05F4B889E7C70238CB451024A8D1B@rie2ksrv1.ri.bbsrc.ac.uk Whole thread Raw |
In response to | combination of function to simple query makes query slow ("jan aerts (RI)" <jan.aerts@bbsrc.ac.uk>) |
Responses |
Re: combination of function to simple query makes query slow
|
List | pgsql-sql |
Some more information: An EXPLAIN of the following query my_db=> explain select m1.object1_id, m1.object2_id, m2.object1_id, m2.object2_id my_db-> from c_mappings m1, c_mappings m2 my_db-> where m1.object1_id = 16575564 my_db-> and m2.object1_idin (select aliases_of(m1.object2_id)); gives: QUERY PLAN ------------------------------------------------------------------------ ----------------------------Nested Loop (cost=0.00..99746.00 rows=1170281 width=16) Join Filter: (subplan) -> Index Scanusing ind_cmappings_object1_id on c_mappings m1 (cost=0.00..6.12 rows=2 width=8) Index Cond: (object1_id = 16575564) -> Seq Scan on c_mappings m2 (cost=0.00..36052.89rows=1435589 width=8) SubPlan -> Result (cost=0.00..0.01 rows=1 width=0) (7 rows) All columns of c_mappings, as well as the columns that are accessed through the aliases_of function, as indexed. However, notice how the second loop uses a "Seq Scan" instead of an "Index Scan". Is there a way to use an index scan on the results of a function? Thanks, jan. > -----Original Message----- > From: pgsql-sql-owner@postgresql.org > [mailto:pgsql-sql-owner@postgresql.org] On Behalf Of jan aerts (RI) > Sent: 30 September 2005 17:02 > To: pgsql-sql@postgresql.org > Subject: [SQL] combination of function to simple query makes > query slow > > 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 = $1 > UNION > SELECT object2_id FROM alias_table WHERE object1_id = $1 > ' > LANGUAGE SQL; > ################################################################ > > > > ---------The obligatory disclaimer-------- The information > contained in this e-mail (including any attachments) is > confidential and is intended for the use of the addressee only. The > opinions expressed within this e-mail (including any > attachments) are the opinions of the sender and do not > necessarily constitute those of Roslin Institute (Edinburgh) > ("the Institute") unless specifically stated by a sender who > is duly authorised to do so on behalf of the Institute. > > ---------------------------(end of > broadcast)--------------------------- > TIP 9: In versions below 8.0, the planner will ignore your desire to > choose an index scan if your joining column's datatypes do not > match >