Reputation: 31
I have a query that takes too long to run and I think is not normal. I am guessing some hints/optimizer would help, but I do not know much about it. So any help would be appreciated.
Basically the code is:
with datasetA as (),
datasetB as (),
datasetC as ()
select a.*
from datasetA a
join datasetB b on b.key = a.key
join datasetC c on c.key = a.key;
Each of the subquery (datasetA, B, C) takes only 1 second to run, but the join takes 30 minutes.... I am 100% sure it is a 1 to 1 join, and the datasets are small (like 1000 rows) and final output is small too.
Upvotes: 1
Views: 9934
Reputation: 36912
Oracle is probably applying a bad optimizer transformation, turning three queries that run fast independently into one query that runs slow. The simplest way to disable those transformations, and ensure that each query runs by itself the fast way, is to add a seemingly worthless ROWNUM
condition, like this:
with datasetA as (... where rownum >= 1),
datasetB as (... where rownum >= 1),
datasetC as (... where rownum >= 1)
select a.*
from datasetA a
join datasetB b on b.key = a.key
join datasetC c on c.key = a.key;
The ROWNUM
pseudo-column was intended for top-N reporting, which wouldn't work if Oracle rewrote each query. So the optimizer leaves those subqueries alone, even though the condition is logically redundant.
Above is the easy way to solve the immediate problem, but not necessarily the best way. You might want to investigate why Oracle is choosing bad transformations; bad optimizer statistics are often the culprit. Finding the root cause may help fix other problems, but can be a difficult process.
If you're curious why Oracle is doing this, optimizer transformations are often a good thing. Transformations like view merging and predicate pushing allow Oracle to apply knowledge from one part of the query to another, which often significantly improves the run time. For example, imagine a query like select * from (select * from huge_table) where primary_key = 1;
. We'd certainly want that predicate to be pushed into the subquery, so Oracle doesn't have to read the whole table just to get one row.
Upvotes: 1
Reputation: 1234
You are likely missing indexes
Follow the below link and it should help you. It should reduce the total execution time of the query by at least 100x
https://www.w3schools.com/sql/sql_create_index.asp
Also, if you could post results from SHOW INDEX FROM table1, SHOW INDEX from table2 we could identify missing indexes
Upvotes: 0
Reputation: 160
you need to add index on join foreign key column on all tables which will improve performance.
Upvotes: 0