Welcome to dbFreaks.com!
FAQFAQ    SearchSearch      ProfileProfile    Private MessagesPrivate Messages   Log inLog in

JOINs against a subquery

 
   Database Help (Home) -> Oracle RSS
Next:  dateadd and conversion  
Author Message
Álvaro_G._Vicario

External


Since: Apr 11, 2008
Posts: 1021



(Msg. 1) Posted: Tue Nov 25, 2008 7:25 am
Post subject: JOINs against a subquery
Archived from groups: comp>databases>oracle>misc (more info?)

I have a pretty complicate query that produces a sales summary,
something similar to this:

customer_id sales_amount
=========== ============
1 99.95
2 125.50
3 1.25

The query is complicate because it reads the table where individual
sales are stored and it needs to filter out some lines according to
variable criteria.

I need to print this data, together with the customer details (full
name, city, etc.). So I join this resultset with the customers table:

customer_id full_name city
=========== ========= ======
1 Joe M. Paris
3 Jack X. London

(Yep, there ain't foreign keys; I'm reading from a third-party database).

My worry is that I must be missing something basic about Oracle. An
INNER JOIN works as expected and is almost as fast as the main query:

SELECT sa.customer_id, sa.sales_amount, cu.full_name, cu.city
FROM (
// Complicate inner query, returns only a few rows
) sa
INNER JOIN customers cu ON sa.customer_id=cu.customer_id

customer_id sales_amount full_name city
=========== ============ ========= ======
1 99.95 Joe M. Paris
3 1.25 Jack X. London

However, a LEFT JOIN takes years to run. The explain plan is completely
different and has a cost that's more than ten times larger. So I cannot
get this:

customer_id sales_amount full_name city
=========== ============ ========= ======
1 99.95 Joe M. Paris
2 125.50 NULL NULL
3 1.25 Jack X. London

I'd say the outer query would run after the inner query is completed but
it doesn't seem to be the case. Am I making a wrong assumption somewhere?


--
-- http://alvaro.es - Álvaro G. Vicario - Burgos, Spain
-- Mi sitio sobre programación web: http://bits.demogracia.com
-- Mi web de humor al baño María: http://www.demogracia.com
--

 >> Stay informed about: JOINs against a subquery 
Back to top
Login to vote
Charles Hooper

External


Since: Dec 18, 2007
Posts: 134



(Msg. 2) Posted: Tue Nov 25, 2008 7:25 am
Post subject: Re: JOINs against a subquery [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

On Nov 25, 7:02 am, "Álvaro G. Vicario"
wrote:
> I have a pretty complicate query that produces a sales summary,
> something similar to this:
>
> customer_id sales_amount
> =========== ============
>            1        99.95
>            2       125.50
>            3         1.25
>
> The query is complicate because it reads the table where individual
> sales are stored and it needs to filter out some lines according to
> variable criteria.
>
> I need to print this data, together with the customer details (full
> name, city, etc.). So I join this resultset with the customers table:
>
> customer_id full_name city
> =========== ========= ======
>            1 Joe M.    Paris
>            3 Jack X.   London
>
> (Yep, there ain't foreign keys; I'm reading from a third-party database).
>
> My worry is that I must be missing something basic about Oracle. An
> INNER JOIN works as expected and is almost as fast as the main query:
>
> SELECT sa.customer_id, sa.sales_amount, cu.full_name, cu.city
> FROM (
>         // Complicate inner query, returns only a few rows
> ) sa
> INNER JOIN customers cu ON sa.customer_id=cu.customer_id
>
> customer_id sales_amount full_name city
> =========== ============ ========= ======
>            1        99.95 Joe M.    Paris
>            3         1.25 Jack X.   London
>
> However, a LEFT JOIN takes years to run. The explain plan is completely
> different and has a cost that's more than ten times larger. So I cannot
> get this:
>
> customer_id sales_amount full_name city
> =========== ============ ========= ======
>            1        99.95 Joe M.    Paris
>            2       125.50 NULL      NULL
>            3         1.25 Jack X.   London
>
> I'd say the outer query would run after the inner query is completed but
> it doesn't seem to be the case. Am I making a wrong assumption somewhere?
>
> --
> --http://alvaro.es- Álvaro G. Vicario - Burgos, Spain

Just a guess as the Oracle version was not specified and the DBMS
Xplans were not posted, but from your description, it sounds like
Oracle is taking the CUSTOMERS table and attempting to drive into the
inline view that you aliased as SA. Essentially, this means that for
each row in the CUSTOMERS table, the full view is resolved. This
seems to happen on more frequently Oracle 10g (R2) than it did in
older versions. You are able to control this behavior through the use
of hints. With a LEADING hint in place to control the driving data
set, the query would look like this:
SELECT /*+ LEADING(SA) */
sa.customer_id, sa.sales_amount, cu.full_name, cu.city
FROM (
// Complicate inner query, returns only a few rows
) sa
LEFT OUTER JOIN customers cu ON sa.customer_id=cu.customer_id;

The Oracle specific syntax, rather than ANSI syntax, looks like this:
SELECT /*+ LEADING(SA) */
sa.customer_id, sa.sales_amount, cu.full_name, cu.city
FROM (
// Complicate inner query, returns only a few rows
) sa,
customers cu
WHERE
sa.customer_id=cu.customer_id(+);

Charles Hooper
IT Manager/Oracle DBA
K&M Machine-Fabricating, Inc.

 >> Stay informed about: JOINs against a subquery 
Back to top
Login to vote
Álvaro_G._Vicario

External


Since: Apr 11, 2008
Posts: 1021



(Msg. 3) Posted: Tue Nov 25, 2008 11:25 am
Post subject: Re: JOINs against a subquery [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Charles Hooper escribió:
> Just a guess as the Oracle version was not specified and the DBMS
> Xplans were not posted, but from your description, it sounds like
> Oracle is taking the CUSTOMERS table and attempting to drive into the
> inline view that you aliased as SA. Essentially, this means that for
> each row in the CUSTOMERS table, the full view is resolved. This
> seems to happen on more frequently Oracle 10g (R2) than it did in
> older versions. You are able to control this behavior through the use
> of hints.

Sorry, I forgot to mention it's 10g R1. I didn't post actual data
because it gets quite complicated and I just wanted some general advise.
(Furthermore, I generate explain plans with SQL Developer and I don't
have the faintest idea of how to export it into a readable format...)

I see my misconception was believing that the subquery was independent
from the external query. No matter how the code looks, the Oracle
optimizer rewrites it all trying to find the optimal execution plan.

I'll have a look at the documentation about optimizer hints.

Thank you very much.



--
-- http://alvaro.es - Álvaro G. Vicario - Burgos, Spain
-- Mi sitio sobre programación web: http://bits.demogracia.com
-- Mi web de humor al baño María: http://www.demogracia.com
--
 >> Stay informed about: JOINs against a subquery 
Back to top
Login to vote
Peter Nilsson

External


Since: Feb 13, 2008
Posts: 13



(Msg. 4) Posted: Wed Nov 26, 2008 5:59 pm
Post subject: Re: JOINs against a subquery [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

"Álvaro G. Vicario" wrote:
> I have a pretty complicate query that produces a sales
> summary, ...
<snip>
> My worry is that I must be missing something basic about
> Oracle. An INNER JOIN works as expected and is almost as
> fast as the main query:
>
> SELECT sa.customer_id, sa.sales_amount, cu.full_name, cu.city
> FROM (
>         // Complicate inner query, returns only a few rows
> ) sa
> INNER JOIN customers cu ON sa.customer_id=cu.customer_id
>
> customer_id sales_amount full_name city
> =========== ============ ========= ======
>            1        99.95 Joe M.    Paris
>            3         1.25 Jack X.   London
>
> However, a LEFT JOIN takes years to run. The explain plan
> is completely different and has a cost that's more than
> ten times larger. So I cannot get this:
>
> customer_id sales_amount full_name city
> =========== ============ ========= ======
>            1        99.95 Joe M.    Paris
>            2       125.50 NULL      NULL
>            3         1.25 Jack X.   London
>
> I'd say the outer query would run after the inner query
> is completed but it doesn't seem to be the case.

Have you tried...

select sa.customer_id,
sa.sales_amount,
(select cu.full_name from customers cu
where cu.customer_id = sa.customer_id) full_name,
(select cu.city from customers cu
where cu.customer_id = sa.customer_id) city
from (...complex...) sa

Although this is notionally slower, if the complex query
is only returning a few rows, then it may work out quicker.

P.S. I'd be inclined to post the complex query.

--
Peter
 >> Stay informed about: JOINs against a subquery 
Back to top
Login to vote
Álvaro_G._Vicario

External


Since: Apr 11, 2008
Posts: 1021



(Msg. 5) Posted: Thu Nov 27, 2008 4:25 am
Post subject: Re: JOINs against a subquery [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Peter Nilsson escribió:
> "Álvaro G. Vicario" wrote:
>> I have a pretty complicate query that produces a sales
>> summary, ...
> <snip>
>> My worry is that I must be missing something basic about
>> Oracle. An INNER JOIN works as expected and is almost as
>> fast as the main query:
>>
>> SELECT sa.customer_id, sa.sales_amount, cu.full_name, cu.city
>> FROM (
>> // Complicate inner query, returns only a few rows
>> ) sa
>> INNER JOIN customers cu ON sa.customer_id=cu.customer_id
>>
>> customer_id sales_amount full_name city
>> =========== ============ ========= ======
>> 1 99.95 Joe M. Paris
>> 3 1.25 Jack X. London
>>
>> However, a LEFT JOIN takes years to run. The explain plan
>> is completely different and has a cost that's more than
>> ten times larger. So I cannot get this:
>>
>> customer_id sales_amount full_name city
>> =========== ============ ========= ======
>> 1 99.95 Joe M. Paris
>> 2 125.50 NULL NULL
>> 3 1.25 Jack X. London
>>
>> I'd say the outer query would run after the inner query
>> is completed but it doesn't seem to be the case.
>
> Have you tried...
>
> select sa.customer_id,
> sa.sales_amount,
> (select cu.full_name from customers cu
> where cu.customer_id = sa.customer_id) full_name,
> (select cu.city from customers cu
> where cu.customer_id = sa.customer_id) city
> from (...complex...) sa
>
> Although this is notionally slower, if the complex query
> is only returning a few rows, then it may work out quicker.

I haven't fined-tuned this query yet, but I've used a similar approach
in another query and it's definitively faster.

The problem was that I had a base misconception about how joins and
subqueries work. Now I understand that the Oracle optimizer can fully
rewrite the query so the order and position in which I write the query
elements do not imply that they'll be executing in that same order. More
specifically, parenthesis do not mean "calculate this first" like in maths.

With this in mind, I'm already getting better performance in several
places (though my SQL looks weirder...)


--
-- http://alvaro.es - Álvaro G. Vicario - Burgos, Spain
-- Mi sitio sobre programación web: http://bits.demogracia.com
-- Mi web de humor al baño María: http://www.demogracia.com
--
 >> Stay informed about: JOINs against a subquery 
Back to top
Login to vote
Display posts from previous:   
Related Topics:
Anyone good with Joins? - Hi, I'm thinking that this should be an outer join, but I am looking for some decent examples. In this query, the conditions are the same. However, the second query contains one extra table/condition/column not in the first query. Right now I am..

"Not in" subquery - Hello, Is there any alternative query to the below one? update RTable set Reason = "XYZ" Where FKey = 1234 and SFKey = 1 and Reason Is Null and F_ID not in ( Select F_ID from RTabl...

SubQuery Question - I have 2 tables that contain Schedule information. The first table contains Work Order's and the second table contains Task information. A given Work Order is composed of any combination of Tasks. Example: Work Order = Car Task 1 = Wheel Install Task 2...

Subquery to lsit - Hi all, ist there a comfortable way to turn a subquery that contains multiple values into a list? Example: Table A: ID - Name ------------- 1 - Bart 2 - Lisa 3 - Homer 4 - Marge Table B: User - Login -------------- 1 - 12:34 2 - 13:41 3 -..

What is the Purpose of Subquery in Insert? - This statement is found in oracle's training material: INSERT INTO (SELECT employee_id, last_name FROM employee WHERE department_id=50) VALUES(9999,'peter'); The above subquery is interpreted as the list columns to be inserted with...
   Database Help (Home) -> Oracle All times are: Pacific Time (US & Canada)
Page 1 of 1

 
You can post new topics in this forum
You can reply to topics in this forum
You can edit your posts in this forum
You can delete your posts in this forum
You can vote in polls in this forum



[ Contact us | Terms of Service/Privacy Policy ]