Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Raj.

Asked: June 25, 2006 - 7:54 pm UTC

Last updated: June 27, 2006 - 9:23 am UTC

Version: 8.1.7 , 9.2.0 and 10.2.0

Viewed 50K+ times! This question is

You Asked

Hi Tom,

In terms of performane, which one is better joins or subquery ?
Can you explain with an example. Also what is difference between nested loops and hash joins and how to determine which one to use from one of them for better performance ? please explain with an example.

Thanks,

Raj

and Tom said...

they (joins/subqueries) are semantically different.

Use a subquery when you need no columns from the tables referenced in the subquery.
Use a join when you do need some of the columns.


select * from emp where deptno in ( select deptno from dept );

would be "better" than


select emp.* from emp, dept where emp.deptno = dept.deptno;


And remember, a subquery cannot simply be replaced by a join (and vice versa), since they often result in DIFFERENT ANSWERS.

The optimizer knows what to do - use the proper construct based on the question being asked. subqueries and joins are NOT interchangeable in general.

If you have access to my book "Effective Oracle by Design", I cover the different access paths and join methods in lots of detail (takes a couple of pages...)

The performance guide:
</code> http://docs.oracle.com/cd/B19306_01/server.102/b14211/toc.htm
covers these topics as well, for example:

http://docs.oracle.com/cd/B19306_01/server.102/b14211/optimops.htm#sthref1385
(nested loops join)
http://docs.oracle.com/cd/B19306_01/server.102/b14211/optimops.htm#sthref1394 <code>
(hash join)




Rating

  (8 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Useful info

Raj, June 26, 2006 - 2:09 pm UTC

Hi Tom,

It was a really useful info and thanks for pointing out to me to the relavant docs. I will surely go through that.

Few questions.
1 >And remember, a subquery cannot simply be replaced by a join (and vice versa),
since they often result in DIFFERENT ANSWERS.
Can you explain this with a short example where join converted as a subquery (and vise versa) producing different results

2 > select * from emp where deptno in ( select deptno from dept );
would be "better" than
select emp.* from emp, dept where emp.deptno = dept.deptno;
why ?

3. Can we re-write following query with outer join using subquery ?
select emp.* from emp, dept where emp.deptno = dept.deptno(+);

Thanks,
Raj.





Tom Kyte
June 26, 2006 - 2:45 pm UTC

1) ops$tkyte@ORA9IR2> select * from scott.dept
  2  where deptno in ( select deptno from scott.emp );
 
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> select dept.* from scott.dept, scott.emp
  2  where dept.deptno = emp.deptno;
 
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        10 ACCOUNTING     NEW YORK
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        20 RESEARCH       DALLAS
        20 RESEARCH       DALLAS
        20 RESEARCH       DALLAS
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        30 SALES          CHICAGO
        30 SALES          CHICAGO
        30 SALES          CHICAGO
        30 SALES          CHICAGO
        30 SALES          CHICAGO
 
14 rows selected.


2) because it does what you are asking - "give me the rows in emp where the emp.deptno is in this (set)"

It askes the question you wanted to ask.  A join does not.

3) why bother?  well, sure - assuming that dept.deptno is a primary key, the rewritten query would be;

select * from emp;


 

Subquery

Girish, June 27, 2006 - 4:56 am UTC

Tom,

What I feel is Oracle internally tranforms all subqueries to joines before result is output and also if just a check is done using EXISTS for exist or not exists condition in a subquery that would be better than getting a row to verify something

What I mean is

select e.* from emp
where exists ( select work from emp_new);

is better than

select e.* from emp
where job in ( select work from emp_new);

When really work column is not required to be retrieved

Hope I am near correct

regds
Girish

Tom Kyte
June 27, 2006 - 7:34 am UTC

"what I feel"

that is not true. Not at all.

"is better than"

that is not true either, not at all.


To the CBO, the above two queries are pretty much "the same".

subquery

Girish, June 27, 2006 - 7:49 am UTC

Tom,

then why most people suggest joined are better than subquery when it comes to performance

/Girish

Tom Kyte
June 27, 2006 - 9:23 am UTC

You would have to ask them?

Why do many people like blue?
Why do many people think a single extent is best?
Or that all indexes should be rebuilt on a schedule?
Or that explicit cursors are better than implicit ones?

Many people believe many strange things.


When someone tells me "X is better than Y", I say "show me, tell me why, show me why, teach me how to measure that what you say is likely true"

Karmit, June 27, 2006 - 9:05 am UTC

>"then why most people suggest joined are better than
>subquery when it comes to performance"...

Because "most people" don't know much about Oracle performance tuning!!

Think about it... if they did then "most" systems would be
trouble free.. clearly not the case in the real world (and
I'm not complaining!)

Don't take at face value what "most people" say - ask
for facts or do it yourself and get the stats.

Subquery

Girish, June 27, 2006 - 11:51 pm UTC

Tom,

All your questions are valid.People here in my company
do not believe even when I show them detailed statistics .
They just go by saying if query is slow they ask me to create index and make it fast.They do not know there is nothing like fast=true.I told them on more than one occasion that try to write query optimized at first step during development.But they ask me that they write it then ask to tune it with HINTS

So is the experience of another DBA

Thsnk for your clarifications

Girish


Llinda, July 27, 2006 - 2:59 pm UTC

"then why most people suggest joined are better than subquery?" -- Girish

Those people are still in stone age (like they started with oracle ver < 6) and still stuck there.

I do have a guy at work who is still living in the stone age also called Girish who thinks that way too. ;)




Thanks a lot Tom !

Nath, August 03, 2006 - 1:44 am UTC

This link cleared one of my biggest doubt..Thank u a lot dear Tom..
But still i'm in Confusion ( by the way..my Oracle experience is just one 1 year. I learnt Oracle just after joining in my current company).

I had been working in an internal project and we decided to use Stored Procedures for reporting (In the previous version of that software they are using java to create the report..means all the validation and calculations had been done in Java.. and that version had a serious performance issues.. ).
When i created procedures for that report it also had performance issue.. it took 30 secs to complete where the requierment from higher management is that they need that report in < 2 secs.. In those procedures i used subqueries
where i need to refer 5 tables.. Required columns i need to fetch is in the 5th table and other tables are referred for some validation checking like date.. LoB etc..
Also we can arrange these 5 tables in a hierarchical order
mean Table5 refers to Table4 ..refers to Table 1
no of record in that table is <10000...
Because of the performance issue i had to sent my packages ot our Oracle techie's and they asked me to change all subqueries to Joins and when i did that my performance issue has been solved... :(
Could u please give any hints based on the above explanation about what could have happend for my procs

all my queries were in a format like
select cols from table5 where key in (select cols from table4 where table4.key in (.... till table 1)

One more sad thing is i usually fought with my collegues who have more Oracle experience than me about the Subquery / Join issue.. They argued for Join..
after this "performance tuning" they flatterd me :(

The first thing i did after reding this link is sending this link to all of them..I have an Oracle Guru(Scientist!) in my team!!!

If i wrote too much sorry for that..

ashish singh rawat, September 08, 2006 - 6:10 am UTC


More to Explore

Performance

Get all the information about database performance in the Database Performance guide.