Skip to content
Advertisement

Does Oracle always resolve CTE with clauses even if they are not used in the result set

If I have an Oracle SQL query like this:

with
    query1 as (
        select * from animals where type = 'dog'
    ),
    query2 as (
        select * from animals where type = 'cat'
    )

select * from query1;

Will the DBMS actually do the work of resolving/running query2, or does Oracle know that query2 is not required by the final output, so the work of that CTE/with should be skipped?

Oracle version is 12c Enterprise.

Advertisement

Answer

I was going going to say “it’s up to the optimizer” or “this is hard to answer” or “you need to look at the execution plan”. But coming up with a single example where the code is not run is sufficient.

So here is an example demonstrating that at least one version of Oracle for at least one example does not evaluate the CTE:

with query1 as (
        select * from animals where type = 'dog'
    ),
    query2 as (
        select a.*, type + 1 from animals a
        
    )
select * from query1;

The second CTE would generate an error if it were evaluated.

This is not a guarantee, of course, that Oracle always ignores unused CTEs. And there could possibly be more arcane explanations for the behavior, but non-evaluation seems like the simplest.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement