I have a very slow query that looks like this:
SELECT *
FROM (
SELECT ..., nn_key_fast(nachname) nnk, ...
FROM t1
JOIN t2 ON
...
JOIN t3 ON
...
JOIN t4 ON
...
WHERE ...
AND t4.POSTCODE='1234'
)
WHERE ... AND nnk LIKE "N%"
Now, the inner select takes ~2min. If I remove the last WHERE clause (t4.POSTCODE), it executes in ~4secs. The result without this clause will be < 1000 records, so a really small set.
So, my thought was: move that clause to the outside SELECT, then it will only be applied to the resulting <1000 records.
But no. The query takes exactly as long, so to be clear:
SELECT *
FROM (
SELECT .....
FROM t1
JOIN t2 ON
...
JOIN t3 ON
...
JOIN t4 ON
...
WHERE ...
)
WHERE ...
AND POSTCODE='1234'
takes the same 2 minutes that the first version takes.
This seems insane to me.
Intuitively, this must be executed by the query optimizer like this: Create a table from the inner select as in:
CREATE TABLE res_from_inner AS (
SELECT .....
FROM t1
JOIN t2 ON
...
JOIN t3 ON
...
JOIN t4 ON
...
WHERE ...
)
... and then do the outer select only on this table, like this:
SELECT *
FROM res_from_inner
WHERE POSTCODE='1234'
And if I do this manually, the CREATE TABLE query takes ~4sec, and the second SELECT takes, as expected < 1sec.
How is this possible, and what to do about it?
SELECT .....? If you use any functions or expressions (liketo_char( x ) as yorx+y as z) in the SELECT clause, the results of which yoou then use in the WHERE clause (likey = '123' or z=22, then Oracle cannot push predicates down to the subquery, indexes are useless and it must be slow. Without details, it's difficult to advise anything here, please show the full query and it's execution plan, for now I vote to close your question as too broad.