473,395 Members | 1,641 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Recursive optimization of IN subqueries

Hi

As far as I can tell, the pull_up_IN_clauses does not optimize
recursively. Am I totally misguided here?

Index: plan/subselect.c
================================================== =================
RCS file:
/projects/cvsroot/pgsql-server/src/backend/optimizer/plan/subselect.c,v
retrieving revision 1.85
diff -u -r1.85 subselect.c
--- plan/subselect.c 25 Nov 2003 23:59:12 -0000 1.85
+++ plan/subselect.c 20 Jan 2004 15:21:55 -0000
@@ -716,6 +716,14 @@
if (contain_volatile_functions((Node *) sublink->lefthand))
return NULL;

+ /*
+ * Optimize recursive
+ */
+ subselect->in_info_list = NIL;
+ if (subselect->hasSubLinks)
+ subselect->jointree->quals = pull_up_IN_clauses(subselect,
+
subselect->jointree->quals);
+
/*
* Okay, pull up the sub-select into top range table and jointree.
*

--
Dennis

---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to ma*******@postgresql.org

Nov 22 '05 #1
3 2526
Dennis Haney <da**@diku.dk> writes:
As far as I can tell, the pull_up_IN_clauses does not optimize
recursively. Am I totally misguided here?


Yes. The subquery is not being physically folded into the outer query
(so the comment about "pulling up" may be a poor choice of words).
It will still get planned separately by a recursive call to
subquery_planner, and any internal INs will get fixed at that time.

It is possible and even rather likely that the subsequent run of
pull_up_subqueries will flatten the subquery into the outer query,
and if so its internal INs are fixed during pull_up_subqueries.
But doing it here would be redundant.

You can easily prove by experiment that multi-level flattening does
happen, for instance:

regression=# explain select * from tenk1 a where unique1 in
regression-# (select unique2 from tenk1 b where unique1 in
regression(# (select thousand from tenk1 c where hundred = 99));
QUERY PLAN

--------------------------------------------------------------------------------
------------------------
Nested Loop (cost=411.66..471.82 rows=10 width=244)
-> HashAggregate (cost=411.66..411.66 rows=10 width=4)
-> Nested Loop (cost=351.47..411.63 rows=10 width=4)
-> HashAggregate (cost=351.47..351.47 rows=10 width=4)
-> Index Scan using tenk1_hundred on tenk1 c (cost=0.00..351.23 rows=99 width=4)
Index Cond: (hundred = 99)
-> Index Scan using tenk1_unique1 on tenk1 b (cost=0.00..6.00 rows=1 width=8)
Index Cond: (b.unique1 = "outer".thousand)
-> Index Scan using tenk1_unique1 on tenk1 a (cost=0.00..6.00 rows=1 width=244)
Index Cond: (a.unique1 = "outer".unique2)
(10 rows)
regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 6: Have you searched our list archives?

http://archives.postgresql.org

Nov 22 '05 #2
Tom Lane wrote:
Dennis Haney <da**@diku.dk> writes:

As far as I can tell, the pull_up_IN_clauses does not optimize
recursively. Am I totally misguided here?


Yes. The subquery is not being physically folded into the outer query
(so the comment about "pulling up" may be a poor choice of words).
It will still get planned separately by a recursive call to
subquery_planner, and any internal INs will get fixed at that time.

It is possible and even rather likely that the subsequent run of
pull_up_subqueries will flatten the subquery into the outer query,
and if so its internal INs are fixed during pull_up_subqueries.
But doing it here would be redundant.

I think I figured it out now, after looking at it for hours...

I saw it as though convert_IN_to_join rewrote the query from

select a.* from tenk1 a where a.unique1 in
(select c.thousand from tenk1 c where c.hundred = 99);

to

select a.* from tenk1 a, tenk1 c where a.unique1 = c.thousand AND
c.hundred = 99;

But after looking at it, I've reached the conclusion that the rewrite is
to this instead:

select a.* from tenk1 a, (select d.thousand from tenk1 d where
d.hundred = 99) as c where a.unique1 = c.thousand;

except the subselect is added as a range table entry instead of a
subselect in the from-list (not that I understand this particular part,
do you mind explaining?).

Or am I still totally lost?

--
Dennis
Nov 22 '05 #3
Dennis Haney <da**@diku.dk> writes:
I saw it as though convert_IN_to_join rewrote the query from select a.* from tenk1 a where a.unique1 in
(select c.thousand from tenk1 c where c.hundred = 99); to select a.* from tenk1 a, tenk1 c where a.unique1 = c.thousand AND
c.hundred = 99; But after looking at it, I've reached the conclusion that the rewrite is
to this instead: select a.* from tenk1 a, (select d.thousand from tenk1 d where
d.hundred = 99) as c where a.unique1 = c.thousand;
Right. We do that, and then subsequently pull_up_subqueries transforms
it to the other representation. The reason for this two-step approach
is that the intermediate form is still a useful improvement if the
subquery can't be pulled up for some reason (e.g., it's got grouping).
except the subselect is added as a range table entry instead of a
subselect in the from-list (not that I understand this particular part,
do you mind explaining?).


Same thing. Every entry in the from-list will have both an RTE and an
entry in the join tree. This representation is partly historical
(before we had outer joins, there was only the range table and no join
tree at all), but it is convenient for many purposes.

regards, tom lane

PS: this is a bit off-topic for pgsql-general, please pursue it on
-hackers if you have more questions.

---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?

http://www.postgresql.org/docs/faqs/FAQ.html

Nov 22 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: Steve Goldman | last post by:
Hi, I am trying to come up with a way to develop all n-length permutations of a given list of values. The short function below seems to work, but I can't help thinking there's a better way. ...
7
by: bearophileHUGS | last post by:
(This is a repost from another python newsgroup). While using some nested data structures, I've seen that I'd like to have a function that tells me if a given data structure contains one or more...
14
by: Bob | last post by:
Hi there, Need a little help with a certain query that's causing a lot of acid in my stomach... Have a table that stores sales measures for a given client. The sales measures are stored per...
7
by: aurora | last post by:
I love generator and I use it a lot. Lately I've been writing some recursive generator to traverse tree structures. After taking closer look I have some concern on its performance. Let's take...
64
by: dmattis | last post by:
I am trying to write a recursive version of Power(x,n) that works by breaking n down into halves(where half of n=n/2), squaring Power(x,n/2), and multiplying by x again if n was odd, and to find a...
7
by: Aloo | last post by:
Dear friends, If we declare a recursive function as 'inline' then does it actually convert to an iterative form during compilation ( the executable code is iterative)? Is it possible ? ...
10
by: zahy[dot]bnaya[At]gmail[dot]com | last post by:
Hi, I am trying to come up with a c style string reverser, I want it to take 1 argument Altough I would never do this in real life. Is there a way to do it? I wrote this function that fails : ...
13
by: jm.suresh | last post by:
Hi, I have a program which literately finds the object that overlapping a point. The horizontal and vertical search are called recursively from inside each other. Is this way of implementation...
6
by: Juha Nieminen | last post by:
Multiple inclusion of the same header file can cause the compilation to fail because of multiple definitions of the same type. That's why it's standard practice to write all headers like this: ...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.