Re: combination of function to simple query makes query slow

From: "jan aerts (RI)" <jan(dot)aerts(at)bbsrc(dot)ac(dot)uk>
To: <pgsql-sql(at)postgresql(dot)org>
Subject: Re: combination of function to simple query makes query slow
Date: 2005-10-03 10:21:18
Message-ID: 84DA9D8AC9B05F4B889E7C70238CB451024A8D1B@rie2ksrv1.ri.bbsrc.ac.uk
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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_id in (select aliases_of(m1.object2_id));
gives:
QUERY PLAN
------------------------------------------------------------------------
----------------------------
Nested Loop (cost=0.00..99746.00 rows=1170281 width=16)
Join Filter: (subplan)
-> Index Scan using 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.89 rows=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(at)postgresql(dot)org
> [mailto:pgsql-sql-owner(at)postgresql(dot)org] On Behalf Of jan aerts (RI)
> Sent: 30 September 2005 17:02
> To: pgsql-sql(at)postgresql(dot)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
>

Responses

Browse pgsql-sql by date

  From Date Subject
Next Message Jaime Casanova 2005-10-03 19:21:42 Re: combination of function to simple query makes query slow
Previous Message Cenk KIZILDAG 2005-10-02 13:30:31 Getting user created tables from SQL