简体   繁体   中英

Oracle 'left outer join' performance issue

I have a block of sql like this:

with X as 
  (
   select * from A 
   left outer join B 
   on A.a1 = B.a1
   and A.b1 = B.b1
   and A.a1 = B.c1
   where a1 = 1
   and b1 = 2
   and c1 = 3 
)
select * from X 

Actually I have 27 blocks of 'WITH' commands which join WITH from one block to the other. Currently the query is running for over one day.. it has only 97 million records..

edit1: Here is the explain plan for one block:

在此处输入图片说明

I don't know which client you are using , but with sqldeveloper for example selecting the query and clicking f10 you will see the explain plain object .

Reading this you will be able to know what is going in full table scan and by clicking ctrl+f12 it will open the tuning advisor tool.

I hope this can help, even if you are not using sqldeveloper, maybe now you know there are tools which help you to find the problem and maybe decide to create indexes for the fields you are using in the where condition.

"here it shows a full table scan is done.. When a query has a 'where' clause.. full table scan should not be done."

Not true at all. You say you have no indexes except for primary keys. What columns are your primary keys? If A(a1,b1,c1) is a compound primary key and B(a1,b1,c1) is also a compound primary key then the index supporting the primary key would be useful in accessing the WHERE clause predicates.

But in all other cases there is no way for the database to know which rows meet the criteria in the WHERE clause except reading every row in the table and comparing the values in the columns. If you're doing that 27 times, no wonder it takes a day.

So probably you need to build indexes on those columns. Also you need to consider whether those 27 WITH clauses are a good idea. Developers like WITH clauses (I include myself) because they support a procedural flow through the query. However relational databases work with sets of data, and procedural flow is usually much less efficient than a set operation. 27 of the blighters seems like a red flag: consider whether there's a better, more SQL-y way of writing the query.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM