Oracle Scratchpad

July 26, 2007

Subquery Factoring (2)

Filed under: Hints, Performance, Tuning — Jonathan Lewis @ 8:24 pm UTC Jul 26,2007

I’ve written about subquery factoring a few times in the past and commented on the use of the /*+ materialize */ hint. Recently I had time to think about what it would take for the Cost Based Optimizer to decide to materialize a subquery without hinting.

I doubt if I have a complete answer yet, and I sometimes wonder if the optimizer code for handling subquery factoring is not yet complete, but my observations are as follows.

The cost (and I do mean the numbers you see in the execution plan output) of materializing a subquery has three factors – the cost of generating the subquery result set, the cost of writing it to disk, and the cost of scanning it back to use it. 

The alternative to materializing is to copy the text into the query body and optimise it there. This leads to two options: either the query is merged, or it is not merged. In 10g the optimizer will (generally) cost both options and take the cheaper.

If it is cheaper to leave the view unmerged then Oracle has to generate the subquery result set anyway – but doesn’t incur the cost of writing it and re-reading it (it goes into the PGA). This means that materializing will always be more expensive than putting the view inline – unless you use the the query result set at least twice in the query.

This is probably why I didn’t need to use a /*+ materialize */ hint in my example of re-writing a piece of bad “internet SQL” a few days ago – my factored subquery appeared twice in the final query.

Warning:

Don’t use subquery factoring casually. Various people have reported examples where the simple presence of a factored subquery has disabled some feature of cost-based query transformation (CBQT) in 10gR2. In practice this means that the following two constructs may not end up using the same execution path – even if the optimizer decides to inline the factored subquery so that it is actually optimizing exactly the same code in both cases:


select  ...
from    (select ... from ...)
;     

with factored_subq as (
        select ... from ...
)
select  ...
from    factored_subq
;     

As a trivial example of the side-effects (or current restrictions, perhaps) of factored subqueries, it is worth noting that it’s only in the most recent release of 10.2 that you can get a star transformation to work if the code has been embedded in a “with” clause.

So be just a little bit careful with the technique – it’s very useful, very clean and tidy, and a good way to control difficult queries: but it may reduce the number of cunning tricks the optimizer can use.

7 Comments »

  1. July 26, 2007? You must have seen http://cosmiclog.msnbc.msn.com/archive/2007/07/17/274531.aspx :-)

    Comment by joel garry — July 19, 2007 @ 10:39 pm UTC Jul 19,2007 | Reply

  2. Hi Jonathan,
    in 92R2 I had some queries where the cost was less when using the materialize hint then not to use it.
    As far as I can remember the effect was that the CBO skiped hashjoins and uses NL insted.

    Regards
    Wolfgang

    Comment by Wolfgang — July 20, 2007 @ 7:27 pm UTC Jul 20,2007 | Reply

  3. [...] Subquery Factoring (2) I’ve written about subquery factoring a few times in the past and commented on the use of the /*+ materialize */ […] [...]

    Pingback by Top Posts « WordPress.com — July 21, 2007 @ 12:01 am UTC Jul 21,2007 | Reply

  4. Joel,
    Just a side-effect of trying to post-date a few articles so that they appeared whilst I was on holiday. (I can do all sorts of things to tweak Oracle – but I haven’t yet managed to get the result out BEFORE running the query).

    Comment by Jonathan Lewis — August 2, 2007 @ 4:08 pm UTC Aug 2,2007 | Reply

  5. Is there a alternative(documented) hint to materialize hint?

    Comment by Dharmendra — August 12, 2008 @ 8:53 pm UTC Aug 12,2008 | Reply

  6. Dharmendra,

    None that I know of. If you have a copy of 11g, you could query view v$sql_hint for clues.

    Comment by Jonathan Lewis — August 19, 2008 @ 6:18 pm UTC Aug 19,2008 | Reply

  7. I’ve been meaning to demonstrate a couple of queries where subquery factoring has changed the way the optimizer handles a query even when it puts the subquery back inline.

    Fortunately I’ve just discovered a couple of examples on Randolf Geist’s blog – so I can just point to that instead of writing my own.

    Comment by Jonathan Lewis — June 3, 2009 @ 8:49 pm UTC Jun 3,2009 | Reply


RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.