<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
		>
<channel>
	<title>Comments on: Brain Teaser: Why is this Query Performing a Full Table Scan</title>
	<atom:link href="http://hoopercharles.wordpress.com/2011/09/14/brain-teaser-why-is-this-query-performing-a-full-table-scan/feed/" rel="self" type="application/rss+xml" />
	<link>http://hoopercharles.wordpress.com/2011/09/14/brain-teaser-why-is-this-query-performing-a-full-table-scan/</link>
	<description>Miscellaneous Random Oracle Topics: Stop, Think, ... Understand</description>
	<lastBuildDate>Mon, 13 May 2013 14:10:06 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<item>
		<title>By: Dom Brooks</title>
		<link>http://hoopercharles.wordpress.com/2011/09/14/brain-teaser-why-is-this-query-performing-a-full-table-scan/#comment-3962</link>
		<dc:creator><![CDATA[Dom Brooks]]></dc:creator>
		<pubDate>Tue, 20 Sep 2011 13:27:37 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=5405#comment-3962</guid>
		<description><![CDATA[Oops - meant to be a reply to Randolf&#039;s comment above.]]></description>
		<content:encoded><![CDATA[<p>Oops &#8211; meant to be a reply to Randolf&#8217;s comment above.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dom Brooks</title>
		<link>http://hoopercharles.wordpress.com/2011/09/14/brain-teaser-why-is-this-query-performing-a-full-table-scan/#comment-3961</link>
		<dc:creator><![CDATA[Dom Brooks]]></dc:creator>
		<pubDate>Tue, 20 Sep 2011 13:26:52 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=5405#comment-3961</guid>
		<description><![CDATA[You&#039;re right - I was talking about the scenario where the checks fail and sampling is not done. 
You were talking about the scenario where the dynamic sampling is actually done but the results rejected.]]></description>
		<content:encoded><![CDATA[<p>You&#8217;re right &#8211; I was talking about the scenario where the checks fail and sampling is not done.<br />
You were talking about the scenario where the dynamic sampling is actually done but the results rejected.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Randolf Geist</title>
		<link>http://hoopercharles.wordpress.com/2011/09/14/brain-teaser-why-is-this-query-performing-a-full-table-scan/#comment-3960</link>
		<dc:creator><![CDATA[Randolf Geist]]></dc:creator>
		<pubDate>Tue, 20 Sep 2011 11:39:43 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=5405#comment-3960</guid>
		<description><![CDATA[Hi Dominic,

I was referring to a slightly different case I think where the dynamic sampling is actually done but result is rejected (and corresponding output can be found in the 10053 trace file) - but you might be correct that the treatment is different when using the dynamic_sampling_est_cdn hint in addition - something I need to test.

I thought you were referring to the case where dynamic sampling does not kick in because statistics have been gathered and default level 2 therefore doesn&#039;t satisfy.

Of course it also depends on whether you mean cursor or table level dynamic sampling with your hint...

Randolf]]></description>
		<content:encoded><![CDATA[<p>Hi Dominic,</p>
<p>I was referring to a slightly different case I think where the dynamic sampling is actually done but result is rejected (and corresponding output can be found in the 10053 trace file) &#8211; but you might be correct that the treatment is different when using the dynamic_sampling_est_cdn hint in addition &#8211; something I need to test.</p>
<p>I thought you were referring to the case where dynamic sampling does not kick in because statistics have been gathered and default level 2 therefore doesn&#8217;t satisfy.</p>
<p>Of course it also depends on whether you mean cursor or table level dynamic sampling with your hint&#8230;</p>
<p>Randolf</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dom Brooks</title>
		<link>http://hoopercharles.wordpress.com/2011/09/14/brain-teaser-why-is-this-query-performing-a-full-table-scan/#comment-3949</link>
		<dc:creator><![CDATA[Dom Brooks]]></dc:creator>
		<pubDate>Sun, 18 Sep 2011 17:29:58 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=5405#comment-3949</guid>
		<description><![CDATA[Hi Randolf,

You&#039;re right about the cardinality.
I had expected to find a cardinality note in the 10053 and didn&#039;t verify before leaping to a conclusion and it&#039;s not there.
A case of 1 + 1 = 3 and a lesson in being thorough.

Regarding your comments on the rejection of dynamic sampling, that was the point of my original comment mentioning this as a possible solution - that if underlying statistics are available then this example SQL won&#039;t use dynamic sampling if you just hint it with /*+ dynamic_sampling() */ but that you could force it using dynamic_sampling_est_cdn. i.e. it can help here but you need the additional hint. 

Cheers,
Dominic]]></description>
		<content:encoded><![CDATA[<p>Hi Randolf,</p>
<p>You&#8217;re right about the cardinality.<br />
I had expected to find a cardinality note in the 10053 and didn&#8217;t verify before leaping to a conclusion and it&#8217;s not there.<br />
A case of 1 + 1 = 3 and a lesson in being thorough.</p>
<p>Regarding your comments on the rejection of dynamic sampling, that was the point of my original comment mentioning this as a possible solution &#8211; that if underlying statistics are available then this example SQL won&#8217;t use dynamic sampling if you just hint it with /*+ dynamic_sampling() */ but that you could force it using dynamic_sampling_est_cdn. i.e. it can help here but you need the additional hint. </p>
<p>Cheers,<br />
Dominic</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Charles Hooper</title>
		<link>http://hoopercharles.wordpress.com/2011/09/14/brain-teaser-why-is-this-query-performing-a-full-table-scan/#comment-3944</link>
		<dc:creator><![CDATA[Charles Hooper]]></dc:creator>
		<pubDate>Sat, 17 Sep 2011 23:11:22 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=5405#comment-3944</guid>
		<description><![CDATA[Randolf,

Great explanations!  (I think that it is safe to say that I would not have been able to drive as deep into this answer as Randolf did, I seem to have forgotten some of these fine details.)

--

I think that everyone who commented in this blog article was certainly headed in the right direction (just some of you were moving a bit faster in that direction).  It is interesting to see how such a simple case of &quot;why isn&#039;t Oracle using my index&quot; has brought out so much helpful information on the topic.]]></description>
		<content:encoded><![CDATA[<p>Randolf,</p>
<p>Great explanations!  (I think that it is safe to say that I would not have been able to drive as deep into this answer as Randolf did, I seem to have forgotten some of these fine details.)</p>
<p>&#8211;</p>
<p>I think that everyone who commented in this blog article was certainly headed in the right direction (just some of you were moving a bit faster in that direction).  It is interesting to see how such a simple case of &#8220;why isn&#8217;t Oracle using my index&#8221; has brought out so much helpful information on the topic.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Randolf Geist</title>
		<link>http://hoopercharles.wordpress.com/2011/09/14/brain-teaser-why-is-this-query-performing-a-full-table-scan/#comment-3943</link>
		<dc:creator><![CDATA[Randolf Geist]]></dc:creator>
		<pubDate>Sat, 17 Sep 2011 19:26:08 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=5405#comment-3943</guid>
		<description><![CDATA[Hi Dominic,

&gt; So, in this case, the absence of a note saying “dynamic sampling used” does not really mean that dynamic sampling was not used.
&gt; It might make more sense in light of what I said in my first comment about dynamic_sampling_est_cdn.

&gt; The dynamic_sampling hint applies to the selectivity of the single table access predicates.
&gt; The “Note” also seems to only apply to that selectivity sampling.

&gt; By using dynamic_sampling(0) we turned off the selectivity sampling (which allowed cardinality feedback to kick in on the subsequent execution if there was one).

&gt; But, there’s no way to turn off the dynamic sampling of the cardinality.
&gt; For example, there is no hint dynamic_sampling_no_est_cdn or no_dynamic_sampling_est_cdn.

Have you verified above? It would mean that you get dynamic sampling for base table cardinality estimates without a note &quot;dynamic sampling used&quot; in the plan output.

I don&#039;t think this is the case. Above figures are actually based on hard-coded defaults - based on the segment size in blocks Oracle multiplies this by a default number of rows per block based on default block size. It&#039;s a bit of coincidence that these defaults actually lead to a base table cardinality that is close to the actual one used in this example here.

There is no dynamic sampling taking place, not even for the base table cardinality, although your explanation sounds quite right with the dynamic_sampling vs. dynamic_sampling_est_cdn.

If you can show me evidence of dynamic sampling taking place here from a 10053 trace file, only then I&#039;ll buy it.

As a side note - this case here can be used as an example where dynamic sampling results can be rejected - however the case needs some modification:
- No index eligible for dynamic sampling (e.g. unindexed complex expression used as filter predicate)
- Underlying statistics available

In such a case if you request dynamic sampling for better selectivity estimates on top this will be rejected in many cases up to quite high levels of dynamic sampling, because Oracle does not find any rows satisfying the filter predicate in the sample and hence rejects the dynamic sampling results until you reach a certain threshold where the majority of table blocks gets sampled.

What I&#039;m trying to say here is that there are cases where dynamic sampling doesn&#039;t help as expected - and the data distribution here represents such an edge case.

Randolf]]></description>
		<content:encoded><![CDATA[<p>Hi Dominic,</p>
<p>&gt; So, in this case, the absence of a note saying “dynamic sampling used” does not really mean that dynamic sampling was not used.<br />
&gt; It might make more sense in light of what I said in my first comment about dynamic_sampling_est_cdn.</p>
<p>&gt; The dynamic_sampling hint applies to the selectivity of the single table access predicates.<br />
&gt; The “Note” also seems to only apply to that selectivity sampling.</p>
<p>&gt; By using dynamic_sampling(0) we turned off the selectivity sampling (which allowed cardinality feedback to kick in on the subsequent execution if there was one).</p>
<p>&gt; But, there’s no way to turn off the dynamic sampling of the cardinality.<br />
&gt; For example, there is no hint dynamic_sampling_no_est_cdn or no_dynamic_sampling_est_cdn.</p>
<p>Have you verified above? It would mean that you get dynamic sampling for base table cardinality estimates without a note &#8220;dynamic sampling used&#8221; in the plan output.</p>
<p>I don&#8217;t think this is the case. Above figures are actually based on hard-coded defaults &#8211; based on the segment size in blocks Oracle multiplies this by a default number of rows per block based on default block size. It&#8217;s a bit of coincidence that these defaults actually lead to a base table cardinality that is close to the actual one used in this example here.</p>
<p>There is no dynamic sampling taking place, not even for the base table cardinality, although your explanation sounds quite right with the dynamic_sampling vs. dynamic_sampling_est_cdn.</p>
<p>If you can show me evidence of dynamic sampling taking place here from a 10053 trace file, only then I&#8217;ll buy it.</p>
<p>As a side note &#8211; this case here can be used as an example where dynamic sampling results can be rejected &#8211; however the case needs some modification:<br />
- No index eligible for dynamic sampling (e.g. unindexed complex expression used as filter predicate)<br />
- Underlying statistics available</p>
<p>In such a case if you request dynamic sampling for better selectivity estimates on top this will be rejected in many cases up to quite high levels of dynamic sampling, because Oracle does not find any rows satisfying the filter predicate in the sample and hence rejects the dynamic sampling results until you reach a certain threshold where the majority of table blocks gets sampled.</p>
<p>What I&#8217;m trying to say here is that there are cases where dynamic sampling doesn&#8217;t help as expected &#8211; and the data distribution here represents such an edge case.</p>
<p>Randolf</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Marcus Mönnig</title>
		<link>http://hoopercharles.wordpress.com/2011/09/14/brain-teaser-why-is-this-query-performing-a-full-table-scan/#comment-3942</link>
		<dc:creator><![CDATA[Marcus Mönnig]]></dc:creator>
		<pubDate>Sat, 17 Sep 2011 06:52:13 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=5405#comment-3942</guid>
		<description><![CDATA[Randolf,

thanks a lot for your answer, which hit the nail on the head. I noticed the difference in the CBO trace file with estimate_percent =&gt; NULL vs. the default value yesterday, but was confused that the basic statistics knew about the 2 dictinct values in both cases.

Marcus]]></description>
		<content:encoded><![CDATA[<p>Randolf,</p>
<p>thanks a lot for your answer, which hit the nail on the head. I noticed the difference in the CBO trace file with estimate_percent =&gt; NULL vs. the default value yesterday, but was confused that the basic statistics knew about the 2 dictinct values in both cases.</p>
<p>Marcus</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Randolf Geist</title>
		<link>http://hoopercharles.wordpress.com/2011/09/14/brain-teaser-why-is-this-query-performing-a-full-table-scan/#comment-3939</link>
		<dc:creator><![CDATA[Randolf Geist]]></dc:creator>
		<pubDate>Fri, 16 Sep 2011 20:25:14 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=5405#comment-3939</guid>
		<description><![CDATA[Marcus,

I think the explanation for your 11.2 result can be seen from the following lines of the 10053 trace file excerpt:

&gt; Histogram: Freq #Bkts: 1 UncompBkts: 5414 EndPtVals: 1
&gt; Using density: 0.500000 of col #10 as selectivity of unpopular value pred
&gt; Table: T1 Alias: T1
&gt; Card: Original: 47789.000000 Rounded: 23895 Computed: 23894.50 Non Adjusted: 23894.50

So you seem to have ended up with a sampled frequency histogram (5414 rows sampled) that consisted of a single popular value - which simply means that due to the sampling the histogram missed the very rare INVALID value. It&#039;s a bad side effect of AUTO_SAMPLE_SIZE in 11g that it uses 100% sampling for the table and basic column statistics but sometimes scales down the sampling size for histograms. This probably has been implemented for performance reasons in order to loose not too much time on the additional gathering iterations required for each histogram, but it can lead to inconsistent statistics - as you can see from the other parts of the 10053 trace file the basic column statistics have covered both values (NDV: 2).

Now combine this inconsistency with the fact that since Oracle 10.2.0.4 a value not found in a frequency histogram will no longer get a cardinality estimate of 1 as it used to be in the past but half of the cardinality of the least popular value - and you end up with a cardinality estimate of 50% of the table, since you have only a single popular value in the histogram that covers 100% of the data...

This bad cardinality estimate drives up the cost of the index access so you end up with the FTS being favoured by the optimizer.

This behaviour can be influenced with a FIX_CONTROL (5483301) if it causes you consist trouble in one of your applications. See &lt;a href=&quot;http://jonathanlewis.wordpress.com/2009/04/23/histogram-change/&quot; rel=&quot;nofollow&quot;&gt;Jonathan&#039;s post&lt;/a&gt; on this and the corresponding comments. The fix control let&#039;s you return to the old behaviour - missing values will get an cardinality estimate of 1.

Repeat your test case on 11.2 with estimate_percent =&gt; NULL or 100 and you should end up with a frequency histogram covering both values and therefore get both a correct cardinality estimate and an index usage.

Which leads back to my initial reply - check the cardinality estimates - bad cardinality estimates are the most common issue with bad execution plans.

Randolf]]></description>
		<content:encoded><![CDATA[<p>Marcus,</p>
<p>I think the explanation for your 11.2 result can be seen from the following lines of the 10053 trace file excerpt:</p>
<p>&gt; Histogram: Freq #Bkts: 1 UncompBkts: 5414 EndPtVals: 1<br />
&gt; Using density: 0.500000 of col #10 as selectivity of unpopular value pred<br />
&gt; Table: T1 Alias: T1<br />
&gt; Card: Original: 47789.000000 Rounded: 23895 Computed: 23894.50 Non Adjusted: 23894.50</p>
<p>So you seem to have ended up with a sampled frequency histogram (5414 rows sampled) that consisted of a single popular value &#8211; which simply means that due to the sampling the histogram missed the very rare INVALID value. It&#8217;s a bad side effect of AUTO_SAMPLE_SIZE in 11g that it uses 100% sampling for the table and basic column statistics but sometimes scales down the sampling size for histograms. This probably has been implemented for performance reasons in order to loose not too much time on the additional gathering iterations required for each histogram, but it can lead to inconsistent statistics &#8211; as you can see from the other parts of the 10053 trace file the basic column statistics have covered both values (NDV: 2).</p>
<p>Now combine this inconsistency with the fact that since Oracle 10.2.0.4 a value not found in a frequency histogram will no longer get a cardinality estimate of 1 as it used to be in the past but half of the cardinality of the least popular value &#8211; and you end up with a cardinality estimate of 50% of the table, since you have only a single popular value in the histogram that covers 100% of the data&#8230;</p>
<p>This bad cardinality estimate drives up the cost of the index access so you end up with the FTS being favoured by the optimizer.</p>
<p>This behaviour can be influenced with a FIX_CONTROL (5483301) if it causes you consist trouble in one of your applications. See <a href="http://jonathanlewis.wordpress.com/2009/04/23/histogram-change/" rel="nofollow">Jonathan&#8217;s post</a> on this and the corresponding comments. The fix control let&#8217;s you return to the old behaviour &#8211; missing values will get an cardinality estimate of 1.</p>
<p>Repeat your test case on 11.2 with estimate_percent =&gt; NULL or 100 and you should end up with a frequency histogram covering both values and therefore get both a correct cardinality estimate and an index usage.</p>
<p>Which leads back to my initial reply &#8211; check the cardinality estimates &#8211; bad cardinality estimates are the most common issue with bad execution plans.</p>
<p>Randolf</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dom Brooks</title>
		<link>http://hoopercharles.wordpress.com/2011/09/14/brain-teaser-why-is-this-query-performing-a-full-table-scan/#comment-3934</link>
		<dc:creator><![CDATA[Dom Brooks]]></dc:creator>
		<pubDate>Thu, 15 Sep 2011 20:20:28 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=5405#comment-3934</guid>
		<description><![CDATA[:)
So, in this case, the absence of a note saying &quot;dynamic sampling used&quot; does not really mean that dynamic sampling was not used.
It might make more sense in light of what I said in my first comment about dynamic_sampling_est_cdn.

The dynamic_sampling hint applies to the selectivity of the single table access predicates.
The &quot;Note&quot; also seems to only apply to that selectivity sampling.

By using dynamic_sampling(0) we turned off the selectivity sampling (which allowed cardinality feedback to kick in on the subsequent execution if there was one).

But, there&#039;s no way to turn off the dynamic sampling of the cardinality.
For example, there is no hint dynamic_sampling_no_est_cdn or no_dynamic_sampling_est_cdn.

So, you then get a standard 1% selectivity estimate on the dynamically sampled cardinality rather than the &quot;1&quot; we migh have expected with no stats and apparently no sampling.

It&#039;s obvious I suppose once you realise what must be going, which I certainly didn&#039;t even notice originally.]]></description>
		<content:encoded><![CDATA[<p> <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
So, in this case, the absence of a note saying &#8220;dynamic sampling used&#8221; does not really mean that dynamic sampling was not used.<br />
It might make more sense in light of what I said in my first comment about dynamic_sampling_est_cdn.</p>
<p>The dynamic_sampling hint applies to the selectivity of the single table access predicates.<br />
The &#8220;Note&#8221; also seems to only apply to that selectivity sampling.</p>
<p>By using dynamic_sampling(0) we turned off the selectivity sampling (which allowed cardinality feedback to kick in on the subsequent execution if there was one).</p>
<p>But, there&#8217;s no way to turn off the dynamic sampling of the cardinality.<br />
For example, there is no hint dynamic_sampling_no_est_cdn or no_dynamic_sampling_est_cdn.</p>
<p>So, you then get a standard 1% selectivity estimate on the dynamically sampled cardinality rather than the &#8220;1&#8243; we migh have expected with no stats and apparently no sampling.</p>
<p>It&#8217;s obvious I suppose once you realise what must be going, which I certainly didn&#8217;t even notice originally.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Charles Hooper</title>
		<link>http://hoopercharles.wordpress.com/2011/09/14/brain-teaser-why-is-this-query-performing-a-full-table-scan/#comment-3933</link>
		<dc:creator><![CDATA[Charles Hooper]]></dc:creator>
		<pubDate>Thu, 15 Sep 2011 20:07:42 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=5405#comment-3933</guid>
		<description><![CDATA[Yes, line 64 in the test case that I posted above (SELECT /*+ dynamic_sampling(0) */ ) that specifically requested no dynamic sampling, was not (apparently) influenced by cardinality feedback, and was not influenced by a modified OPTIMIZER_INDEX_COST_ADJ parameter - that index access path surprised me.  I might experiment a bit more later to see if I can determine what happened.]]></description>
		<content:encoded><![CDATA[<p>Yes, line 64 in the test case that I posted above (SELECT /*+ dynamic_sampling(0) */ ) that specifically requested no dynamic sampling, was not (apparently) influenced by cardinality feedback, and was not influenced by a modified OPTIMIZER_INDEX_COST_ADJ parameter &#8211; that index access path surprised me.  I might experiment a bit more later to see if I can determine what happened.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
