<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/2.3.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>
<channel>
	<title>Comments on: Bind Peeking, Ad Hoc Queries, Stable Performance. On 10G you can only pick any two.</title>
	<link>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two</link>
	<description>News and views from Pythian DBAs</description>
	<pubDate>Sat, 22 Nov 2008 09:39:24 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.2</generator>
		<item>
		<title>By: L&#8217;ottimizzatore basato sui costi: CBO &#171; Oracle and other</title>
		<link>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-176002</link>
		<dc:creator>L&#8217;ottimizzatore basato sui costi: CBO &#171; Oracle and other</dc:creator>
		<pubDate>Thu, 03 Apr 2008 14:11:08 +0000</pubDate>
		<guid>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-176002</guid>
		<description>[...] caso il paragrafo su RBO, insieme ad alcuni post come ad esempio questo sul blog di Doug Burns, poi quello di Christo Kutrovsky sul blog di pythian seguito da un post di Alex Faktulin sugli istogrammi, mi hanno fatto riflettere e cambiare un [...]</description>
		<content:encoded><![CDATA[<p>[&#8230;] caso il paragrafo su RBO, insieme ad alcuni post come ad esempio questo sul blog di Doug Burns, poi quello di Christo Kutrovsky sul blog di pythian seguito da un post di Alex Faktulin sugli istogrammi, mi hanno fatto riflettere e cambiare un [&#8230;]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Christo Kutrovsky</title>
		<link>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-171935</link>
		<dc:creator>Christo Kutrovsky</dc:creator>
		<pubDate>Tue, 18 Mar 2008 14:29:07 +0000</pubDate>
		<guid>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-171935</guid>
		<description>Yas, I will look into the email follow up option.</description>
		<content:encoded><![CDATA[<p>Yas, I will look into the email follow up option.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: yas</title>
		<link>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-171933</link>
		<dc:creator>yas</dc:creator>
		<pubDate>Tue, 18 Mar 2008 14:23:37 +0000</pubDate>
		<guid>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-171933</guid>
		<description>Christo, it is definitely correct that using the other value for the bind parameter will make it much worse than disabling bind peeking. But what I suggested is not to bind it at all, as I said "I prefer keeping it enabled and changing the code to use literals (if there are not many different values queried of course) when one wants to guarantee the best plan.".

I think we agree that for such a query using literals is the best solution.

By they way, it will really help if you can make a change to the blog to e-mail follow-up comments if someone commented on a post.</description>
		<content:encoded><![CDATA[<p>Christo, it is definitely correct that using the other value for the bind parameter will make it much worse than disabling bind peeking. But what I suggested is not to bind it at all, as I said &#8220;I prefer keeping it enabled and changing the code to use literals (if there are not many different values queried of course) when one wants to guarantee the best plan.&#8221;.</p>
<p>I think we agree that for such a query using literals is the best solution.</p>
<p>By they way, it will really help if you can make a change to the blog to e-mail follow-up comments if someone commented on a post.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: cristiancudizio</title>
		<link>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-171849</link>
		<dc:creator>cristiancudizio</dc:creator>
		<pubDate>Tue, 18 Mar 2008 08:33:17 +0000</pubDate>
		<guid>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-171849</guid>
		<description>Good answer, i like it a lot, i've tested it and it works well. 
Compliments again.

Cheers,

 Cristian</description>
		<content:encoded><![CDATA[<p>Good answer, i like it a lot, i&#8217;ve tested it and it works well.<br />
Compliments again.</p>
<p>Cheers,</p>
<p> Cristian</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Christo Kutrovsky</title>
		<link>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-171715</link>
		<dc:creator>Christo Kutrovsky</dc:creator>
		<pubDate>Mon, 17 Mar 2008 21:30:47 +0000</pubDate>
		<guid>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-171715</guid>
		<description>cristiancudizio:

I did a bit more experimenting and just realized. You must have quite the skew in order to have 3 equal predicates and still get a FTS.

Anyways, you can avoid this by doing (with peeking turned off):

where a = :a 
and a &lt;&gt; -1

where -1 is your popular value. 

That way you are telling Oracle "I have an unknown value, but it's not a popular one". You could do the opposite by using between. Those are also in a way workarounds, but I think it's significantly more reliable like that. 

This will have the same effects as if your 'default' value was null to begin with. It changes your logic a bit, but ... if you ever expect to get -1 as an argument, then it will be quite slow for that one 'call'.
And if it happens to be parsed with -1's then everything will be slow ;)</description>
		<content:encoded><![CDATA[<p>cristiancudizio:</p>
<p>I did a bit more experimenting and just realized. You must have quite the skew in order to have 3 equal predicates and still get a FTS.</p>
<p>Anyways, you can avoid this by doing (with peeking turned off):</p>
<p>where a = :a<br />
and a <> -1</p>
<p>where -1 is your popular value. </p>
<p>That way you are telling Oracle &#8220;I have an unknown value, but it&#8217;s not a popular one&#8221;. You could do the opposite by using between. Those are also in a way workarounds, but I think it&#8217;s significantly more reliable like that. </p>
<p>This will have the same effects as if your &#8216;default&#8217; value was null to begin with. It changes your logic a bit, but &#8230; if you ever expect to get -1 as an argument, then it will be quite slow for that one &#8216;call&#8217;.<br />
And if it happens to be parsed with -1&#8217;s then everything will be slow ;)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Christo Kutrovsky</title>
		<link>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-171707</link>
		<dc:creator>Christo Kutrovsky</dc:creator>
		<pubDate>Mon, 17 Mar 2008 20:45:18 +0000</pubDate>
		<guid>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-171707</guid>
		<description>cristiancudizio:

I see your point. See, that's the problem with using dummy values. Had you used nulls, you wouldn't have this problem. Not to mention a bit of space saved in the table, and a lot of space saved in the index.

What you can do in such cases is patchup the statistics and have your a/b/c columns look more selective, but leave the histograms as is.

Whenever you use the fixed values (-1) dont bind and the histograms will show the right plan. Whenever you bind, you will always use index.</description>
		<content:encoded><![CDATA[<p>cristiancudizio:</p>
<p>I see your point. See, that&#8217;s the problem with using dummy values. Had you used nulls, you wouldn&#8217;t have this problem. Not to mention a bit of space saved in the table, and a lot of space saved in the index.</p>
<p>What you can do in such cases is patchup the statistics and have your a/b/c columns look more selective, but leave the histograms as is.</p>
<p>Whenever you use the fixed values (-1) dont bind and the histograms will show the right plan. Whenever you bind, you will always use index.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: cristiancudizio</title>
		<link>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-171596</link>
		<dc:creator>cristiancudizio</dc:creator>
		<pubDate>Mon, 17 Mar 2008 16:50:04 +0000</pubDate>
		<guid>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-171596</guid>
		<description>Thanks for you answer. Really i was to lazy to post you the complete example. However i've made an error. The unused values are filled with a dummy value (-1).
In my case bind peeking makes a good job because bind values are "omogeneous" to those used in bind peeking, as if they are the same value, but they are not the same value. On the other  hand in my terrible situation if it would not be so, performance would be never good. Histograms say's that value picked is high selective, on the other hand an unknown value (as without bind peeking) make's optimizer guess that value maybe  -1 those of 2/3 of the records and thinking that's better a full scan.  So, select * from TEST where
a= :a or b=:B or c=:c is called a lot of times so, binding is better, values for :a :b and :c are always -1 and so it is better to use index. Firts time that query is parsed bind peeking plus histograms make CBO calculate a better execution plan based on indexes on the three columns. Without bind peeking Oracle does not know that i'm passing a very selective value and choose to make a full scan.
Maybe that this is bad design, but with CBO and bind peeking works well, as it worked well with RBO. 
I hope i've been able to explain my example. 
Thanks again for your attention.

Regards,
  Cristian</description>
		<content:encoded><![CDATA[<p>Thanks for you answer. Really i was to lazy to post you the complete example. However i&#8217;ve made an error. The unused values are filled with a dummy value (-1).<br />
In my case bind peeking makes a good job because bind values are &#8220;omogeneous&#8221; to those used in bind peeking, as if they are the same value, but they are not the same value. On the other  hand in my terrible situation if it would not be so, performance would be never good. Histograms say&#8217;s that value picked is high selective, on the other hand an unknown value (as without bind peeking) make&#8217;s optimizer guess that value maybe  -1 those of 2/3 of the records and thinking that&#8217;s better a full scan.  So, select * from TEST where<br />
a= :a or b=:B or c=:c is called a lot of times so, binding is better, values for :a :b and :c are always -1 and so it is better to use index. Firts time that query is parsed bind peeking plus histograms make CBO calculate a better execution plan based on indexes on the three columns. Without bind peeking Oracle does not know that i&#8217;m passing a very selective value and choose to make a full scan.<br />
Maybe that this is bad design, but with CBO and bind peeking works well, as it worked well with RBO.<br />
I hope i&#8217;ve been able to explain my example.<br />
Thanks again for your attention.</p>
<p>Regards,<br />
  Cristian</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Christo Kutrovsky</title>
		<link>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-171542</link>
		<dc:creator>Christo Kutrovsky</dc:creator>
		<pubDate>Mon, 17 Mar 2008 12:16:42 +0000</pubDate>
		<guid>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-171542</guid>
		<description>Cristian Cudizio: 

In 11g where bind peeking works based on the value, and creates multiple plans, it is probably doing a good job. (Havent tested yet).

But in 10g it does terrible job, unless you are always binding the same value. And if you are always binding the same value, why bind? (assuming it's static, and no sql injection can happen).</description>
		<content:encoded><![CDATA[<p>Cristian Cudizio: </p>
<p>In 11g where bind peeking works based on the value, and creates multiple plans, it is probably doing a good job. (Havent tested yet).</p>
<p>But in 10g it does terrible job, unless you are always binding the same value. And if you are always binding the same value, why bind? (assuming it&#8217;s static, and no sql injection can happen).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Christo Kutrovsky</title>
		<link>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-171539</link>
		<dc:creator>Christo Kutrovsky</dc:creator>
		<pubDate>Mon, 17 Mar 2008 12:14:23 +0000</pubDate>
		<guid>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-171539</guid>
		<description>Yas,

What would you prefer a system that runs at 90% performance consistently, or a system that runs at 99% performance, but occasionally a job never finishes, or a web page takes 30 seconds?

In your example, I am sure you know what happens when you re-execute the same query with :b=0. 

I was asking for a test case where having bind peeking on, is consistently superior then having it off. In your case, for 1 of the 40 000 values your query will run faster. For all other values, it will be significantly slower.

test&gt; select * from t where status=:b1;

Elapsed: 00:00:00.02

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
        576  bytes sent via SQL*Net to client
        492  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

test&gt; exec :b1 := 0;

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.01
test&gt; select * from t where status=:b1;

40781 rows selected.

Elapsed: 00:00:00.12

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       5580  consistent gets
          0  physical reads
          0  redo size
     895309  bytes sent via SQL*Net to client
      30390  bytes received via SQL*Net from client
       2720  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      40781  rows processed

test&gt; alter session set "_optim_peek_user_binds"=false;

Session altered.

Elapsed: 00:00:00.01
test&gt; select * from t where status=:b1;

40781 rows selected.

Elapsed: 00:00:00.12

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
       2795  consistent gets
          0  physical reads
          0  redo size
     895309  bytes sent via SQL*Net to client
      30390  bytes received via SQL*Net from client
       2720  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      40781  rows processed</description>
		<content:encoded><![CDATA[<p>Yas,</p>
<p>What would you prefer a system that runs at 90% performance consistently, or a system that runs at 99% performance, but occasionally a job never finishes, or a web page takes 30 seconds?</p>
<p>In your example, I am sure you know what happens when you re-execute the same query with :b=0. </p>
<p>I was asking for a test case where having bind peeking on, is consistently superior then having it off. In your case, for 1 of the 40 000 values your query will run faster. For all other values, it will be significantly slower.</p>
<p>test> select * from t where status=:b1;</p>
<p>Elapsed: 00:00:00.02</p>
<p>Statistics<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
          1  recursive calls<br />
          0  db block gets<br />
          3  consistent gets<br />
          0  physical reads<br />
          0  redo size<br />
        576  bytes sent via SQL*Net to client<br />
        492  bytes received via SQL*Net from client<br />
          2  SQL*Net roundtrips to/from client<br />
          0  sorts (memory)<br />
          0  sorts (disk)<br />
          1  rows processed</p>
<p>test> exec :b1 := 0;</p>
<p>PL/SQL procedure successfully completed.</p>
<p>Elapsed: 00:00:00.01<br />
test> select * from t where status=:b1;</p>
<p>40781 rows selected.</p>
<p>Elapsed: 00:00:00.12</p>
<p>Statistics<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
          0  recursive calls<br />
          0  db block gets<br />
       5580  consistent gets<br />
          0  physical reads<br />
          0  redo size<br />
     895309  bytes sent via SQL*Net to client<br />
      30390  bytes received via SQL*Net from client<br />
       2720  SQL*Net roundtrips to/from client<br />
          0  sorts (memory)<br />
          0  sorts (disk)<br />
      40781  rows processed</p>
<p>test> alter session set &#8220;_optim_peek_user_binds&#8221;=false;</p>
<p>Session altered.</p>
<p>Elapsed: 00:00:00.01<br />
test> select * from t where status=:b1;</p>
<p>40781 rows selected.</p>
<p>Elapsed: 00:00:00.12</p>
<p>Statistics<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
          1  recursive calls<br />
          0  db block gets<br />
       2795  consistent gets<br />
          0  physical reads<br />
          0  redo size<br />
     895309  bytes sent via SQL*Net to client<br />
      30390  bytes received via SQL*Net from client<br />
       2720  SQL*Net roundtrips to/from client<br />
          0  sorts (memory)<br />
          0  sorts (disk)<br />
      40781  rows processed</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Log Buffer #88: a Carnival of the Vanities for DBAs</title>
		<link>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-170791</link>
		<dc:creator>Log Buffer #88: a Carnival of the Vanities for DBAs</dc:creator>
		<pubDate>Fri, 14 Mar 2008 16:56:45 +0000</pubDate>
		<guid>http://www.pythian.com/blogs/820/bind-peeking-ad-hoc-queries-stable-performance-on-10g-you-can-only-pick-any-two#comment-170791</guid>
		<description>[...] another local post, Christo Kutrovsky writes that, on 10G you can only pick any two of bind peeking, ad hoc queries, and stable performance. &#8220;There have been plenty of posts about bind peeking. .&#160;.&#160;. It’s a well known [...]</description>
		<content:encoded><![CDATA[<p>[&#8230;] another local post, Christo Kutrovsky writes that, on 10G you can only pick any two of bind peeking, ad hoc queries, and stable performance. &#8220;There have been plenty of posts about bind peeking. .&nbsp;.&nbsp;. It’s a well known [&#8230;]</p>
]]></content:encoded>
	</item>
</channel>
</rss>
