<?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: PK Problem</title>
	<atom:link href="http://jonathanlewis.wordpress.com/2012/07/12/pk-problem/feed/" rel="self" type="application/rss+xml" />
	<link>http://jonathanlewis.wordpress.com/2012/07/12/pk-problem/</link>
	<description>Just another Oracle weblog</description>
	<lastBuildDate>Tue, 18 Jun 2013 17:11:36 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<item>
		<title>By: Jonathan Lewis</title>
		<link>http://jonathanlewis.wordpress.com/2012/07/12/pk-problem/#comment-48115</link>
		<dc:creator><![CDATA[Jonathan Lewis]]></dc:creator>
		<pubDate>Thu, 19 Jul 2012 10:48:05 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=9162#comment-48115</guid>
		<description><![CDATA[Jason,

Hash partitioning the index is a good strategy (if you&#039;ve got the license) for reducing buffer busy waits on the high-values end of a sequential or time-based index; and if you do need to rebuild the index from time to time it&#039;s nice to be able to rebuild it in parts; but partitioning doesn&#039;t affect the SQL used to check for uniqueness.

As Pete points out - a billion generally defaults to the US standard of 10e9.]]></description>
		<content:encoded><![CDATA[<p>Jason,</p>
<p>Hash partitioning the index is a good strategy (if you&#8217;ve got the license) for reducing buffer busy waits on the high-values end of a sequential or time-based index; and if you do need to rebuild the index from time to time it&#8217;s nice to be able to rebuild it in parts; but partitioning doesn&#8217;t affect the SQL used to check for uniqueness.</p>
<p>As Pete points out &#8211; a billion generally defaults to the US standard of 10e9.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jonathan Lewis</title>
		<link>http://jonathanlewis.wordpress.com/2012/07/12/pk-problem/#comment-48110</link>
		<dc:creator><![CDATA[Jonathan Lewis]]></dc:creator>
		<pubDate>Thu, 19 Jul 2012 09:42:59 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=9162#comment-48110</guid>
		<description><![CDATA[Valentin,

That&#039;s a brilliant workaround. 
I think the ORA-30389 is a re-interpretation of the underlying ORA-32023 because Oracle tests the validity of the destination statement by attempting to parse a statement of the form:
[sourcecode]
(old_statement)
union all
(new_statement)

-- example

select object_id from user_objects
union all
with v1 as (select data_object_id  from user_objects)

[/sourcecode]

Conveniently your workaround hides the factored subquery from the union all.]]></description>
		<content:encoded><![CDATA[<p>Valentin,</p>
<p>That&#8217;s a brilliant workaround.<br />
I think the ORA-30389 is a re-interpretation of the underlying ORA-32023 because Oracle tests the validity of the destination statement by attempting to parse a statement of the form:</p>
<pre class="brush: plain; title: ; notranslate">
(old_statement)
union all
(new_statement)

-- example

select object_id from user_objects
union all
with v1 as (select data_object_id  from user_objects)

</pre>
<p>Conveniently your workaround hides the factored subquery from the union all.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Pete</title>
		<link>http://jonathanlewis.wordpress.com/2012/07/12/pk-problem/#comment-48057</link>
		<dc:creator><![CDATA[Pete]]></dc:creator>
		<pubDate>Tue, 17 Jul 2012 16:45:38 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=9162#comment-48057</guid>
		<description><![CDATA[Hi
For the record the quoted table size meant one thousand eight hundred million . The American definition of a billion won out a long time around the globe and is now the official meaning of a &quot;Billion&quot; in the U.K. As for partitioning, well in this case anything only hash partitioning may be possible because there is nothing of use in the table definition to range or list partition by. This was casually mentioned to me by the development team, who looked somewhat bemused when I told them that you have to plan this sort of thing up front! So this is what I am looking at next.

Thanks to Jonathan for the posts on Oracle-L and this blog entry.

Pete]]></description>
		<content:encoded><![CDATA[<p>Hi<br />
For the record the quoted table size meant one thousand eight hundred million . The American definition of a billion won out a long time around the globe and is now the official meaning of a &#8220;Billion&#8221; in the U.K. As for partitioning, well in this case anything only hash partitioning may be possible because there is nothing of use in the table definition to range or list partition by. This was casually mentioned to me by the development team, who looked somewhat bemused when I told them that you have to plan this sort of thing up front! So this is what I am looking at next.</p>
<p>Thanks to Jonathan for the posts on Oracle-L and this blog entry.</p>
<p>Pete</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jason Bucata</title>
		<link>http://jonathanlewis.wordpress.com/2012/07/12/pk-problem/#comment-48017</link>
		<dc:creator><![CDATA[Jason Bucata]]></dc:creator>
		<pubDate>Mon, 16 Jul 2012 18:19:43 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=9162#comment-48017</guid>
		<description><![CDATA[Would globally hash-partitioning the index change the situation any?  For a sufficiently large table it&#039;s a good idea anyway (assuming partitioning is licensed, of course).

Oh, and since you&#039;re a Brit, does &quot;Billion with a B&quot; mean 1e9 or 1e12 (which would be a trillion to us Yankees)?  If the latter, hash partitioning the index sounds like an even better idea.]]></description>
		<content:encoded><![CDATA[<p>Would globally hash-partitioning the index change the situation any?  For a sufficiently large table it&#8217;s a good idea anyway (assuming partitioning is licensed, of course).</p>
<p>Oh, and since you&#8217;re a Brit, does &#8220;Billion with a B&#8221; mean 1e9 or 1e12 (which would be a trillion to us Yankees)?  If the latter, hash partitioning the index sounds like an even better idea.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Valentin Nikotin</title>
		<link>http://jonathanlewis.wordpress.com/2012/07/12/pk-problem/#comment-47980</link>
		<dc:creator><![CDATA[Valentin Nikotin]]></dc:creator>
		<pubDate>Sun, 15 Jul 2012 19:18:45 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=9162#comment-47980</guid>
		<description><![CDATA[The last thing for which I couldn&#039;t find any workaround is

[sourcecode language=&quot;SQL&quot;]
*
ERROR at line 1:
ORA-30353: expression not supported for query rewrite
ORA-06512: at &quot;SYS.DBMS_ADVANCED_REWRITE&quot;, line 29
ORA-06512: at &quot;SYS.DBMS_ADVANCED_REWRITE&quot;, line 185
ORA-06512: at line 13[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>The last thing for which I couldn&#8217;t find any workaround is</p>
<pre class="brush: sql; title: ; notranslate">
*
ERROR at line 1:
ORA-30353: expression not supported for query rewrite
ORA-06512: at &quot;SYS.DBMS_ADVANCED_REWRITE&quot;, line 29
ORA-06512: at &quot;SYS.DBMS_ADVANCED_REWRITE&quot;, line 185
ORA-06512: at line 13</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Valentin Nikotin</title>
		<link>http://jonathanlewis.wordpress.com/2012/07/12/pk-problem/#comment-47948</link>
		<dc:creator><![CDATA[Valentin Nikotin]]></dc:creator>
		<pubDate>Sat, 14 Jul 2012 10:11:49 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=9162#comment-47948</guid>
		<description><![CDATA[Hi Jonathan, please take a simple trick to avoid &quot;unsupported use of WITH clause&quot;:
[sourcecode language=&quot;SQL&quot; collapse=&quot;true&quot;]
SQL&gt; begin
  2          sys.dbms_advanced_rewrite.declare_rewrite_equivalence(
  3                  name             =&gt; &#039;TEST_HINT2&#039;,
  4                  source_stmt      =&gt; &#039;select * from usr.t1 where n1 = 15&#039;,
  5                  destination_stmt =&gt;
  6                          &#039;with a as (select /*+ index(v1.t1) */ * from usr.v1 where n1 = 15) select * from a&#039;,
  7                  validate         =&gt; false,
  8                  rewrite_mode     =&gt; &#039;general&#039;
  9          );
 10  end;
 11  /
 
begin
        sys.dbms_advanced_rewrite.declare_rewrite_equivalence(
                name             =&gt; &#039;TEST_HINT2&#039;,
                source_stmt      =&gt; &#039;select * from usr.t1 where n1 = 15&#039;,
                destination_stmt =&gt;
                        &#039;with a as (select /*+ index(v1.t1) */ * from usr.v1 where n1 = 15) select * from a&#039;,
                validate         =&gt; false,
                rewrite_mode     =&gt; &#039;general&#039;
        );
end;
 
ORA-30389: the source statement is not compatible with the destination statement
ORA-32034: unsupported use of WITH clause
ORA-06512: at &quot;SYS.DBMS_ADVANCED_REWRITE&quot;, line 29
ORA-06512: at &quot;SYS.DBMS_ADVANCED_REWRITE&quot;, line 185
ORA-06512: at line 3

SQL&gt; begin
  2          sys.dbms_advanced_rewrite.declare_rewrite_equivalence(
  3                  name             =&gt; &#039;TEST_HINT2&#039;,
  4                  source_stmt      =&gt; &#039;select * from usr.t1 where n1 = 15&#039;,
  5                  destination_stmt =&gt;
  6                          &#039;select * from (with a as (select /*+ index(v1.t1) */ * from usr.v1 where n1 = 15) select * from a)&#039;,
  7                  validate         =&gt; false,
  8                  rewrite_mode     =&gt; &#039;general&#039;
  9          );
 10  end;
 11  /
 
PL/SQL procedure successfully completed
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>Hi Jonathan, please take a simple trick to avoid &#8220;unsupported use of WITH clause&#8221;:</p>
<pre class="brush: sql; collapse: true; light: false; title: ; toolbar: true; notranslate">
SQL&gt; begin
  2          sys.dbms_advanced_rewrite.declare_rewrite_equivalence(
  3                  name             =&gt; 'TEST_HINT2',
  4                  source_stmt      =&gt; 'select * from usr.t1 where n1 = 15',
  5                  destination_stmt =&gt;
  6                          'with a as (select /*+ index(v1.t1) */ * from usr.v1 where n1 = 15) select * from a',
  7                  validate         =&gt; false,
  8                  rewrite_mode     =&gt; 'general'
  9          );
 10  end;
 11  /
 
begin
        sys.dbms_advanced_rewrite.declare_rewrite_equivalence(
                name             =&gt; 'TEST_HINT2',
                source_stmt      =&gt; 'select * from usr.t1 where n1 = 15',
                destination_stmt =&gt;
                        'with a as (select /*+ index(v1.t1) */ * from usr.v1 where n1 = 15) select * from a',
                validate         =&gt; false,
                rewrite_mode     =&gt; 'general'
        );
end;
 
ORA-30389: the source statement is not compatible with the destination statement
ORA-32034: unsupported use of WITH clause
ORA-06512: at &quot;SYS.DBMS_ADVANCED_REWRITE&quot;, line 29
ORA-06512: at &quot;SYS.DBMS_ADVANCED_REWRITE&quot;, line 185
ORA-06512: at line 3

SQL&gt; begin
  2          sys.dbms_advanced_rewrite.declare_rewrite_equivalence(
  3                  name             =&gt; 'TEST_HINT2',
  4                  source_stmt      =&gt; 'select * from usr.t1 where n1 = 15',
  5                  destination_stmt =&gt;
  6                          'select * from (with a as (select /*+ index(v1.t1) */ * from usr.v1 where n1 = 15) select * from a)',
  7                  validate         =&gt; false,
  8                  rewrite_mode     =&gt; 'general'
  9          );
 10  end;
 11  /
 
PL/SQL procedure successfully completed
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Log Buffer #277, A Carnival of the Vanities for DBAs &#124; The Pythian Blog</title>
		<link>http://jonathanlewis.wordpress.com/2012/07/12/pk-problem/#comment-47944</link>
		<dc:creator><![CDATA[Log Buffer #277, A Carnival of the Vanities for DBAs &#124; The Pythian Blog]]></dc:creator>
		<pubDate>Sat, 14 Jul 2012 04:19:08 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=9162#comment-47944</guid>
		<description><![CDATA[[...] the constraint in the state enable novalidate, and then validate the constraint, a cool advice from Jonathan once [...]]]></description>
		<content:encoded><![CDATA[<p>[...] the constraint in the state enable novalidate, and then validate the constraint, a cool advice from Jonathan once [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: savvinov</title>
		<link>http://jonathanlewis.wordpress.com/2012/07/12/pk-problem/#comment-47911</link>
		<dc:creator><![CDATA[savvinov]]></dc:creator>
		<pubDate>Fri, 13 Jul 2012 13:50:45 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=9162#comment-47911</guid>
		<description><![CDATA[Hi Jonathan,

a great post, and very practical, too. I imagine that it could have a much wider application than making PK validation faster -- it&#039;s probably not the only place in Oracle internal code where an inefficient plan is hardwired for a maintenance operation. E.g. I hate the way Oracle implemented redefinition of multiple columns in one ALTER TABLE (in my case Oracle was doing as many full table scans as the number of columns to be modified) -- and even though in this particular case the tricks you described won&#039;t work, I would tend to believe there are dozens similar cases when they might help.

Best regards,
  Nikolay]]></description>
		<content:encoded><![CDATA[<p>Hi Jonathan,</p>
<p>a great post, and very practical, too. I imagine that it could have a much wider application than making PK validation faster &#8212; it&#8217;s probably not the only place in Oracle internal code where an inefficient plan is hardwired for a maintenance operation. E.g. I hate the way Oracle implemented redefinition of multiple columns in one ALTER TABLE (in my case Oracle was doing as many full table scans as the number of columns to be modified) &#8212; and even though in this particular case the tricks you described won&#8217;t work, I would tend to believe there are dozens similar cases when they might help.</p>
<p>Best regards,<br />
  Nikolay</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: rsiz</title>
		<link>http://jonathanlewis.wordpress.com/2012/07/12/pk-problem/#comment-47868</link>
		<dc:creator><![CDATA[rsiz]]></dc:creator>
		<pubDate>Thu, 12 Jul 2012 18:32:00 +0000</pubDate>
		<guid isPermaLink="false">http://jonathanlewis.wordpress.com/?p=9162#comment-47868</guid>
		<description><![CDATA[Interesting study indeed!

I *hope* it leads to Oracle performing pk constraint validations explicitly by treewalk(not fast) full index scan when over size X. Where you only have to keep 1 previous value (and the start of the next section if parallel) in memory per parallel thread, and even with exception tracking only the duplicates need to get written. Parallel scan points could be picked from the starting node and a thread finishing would pick up a point not yet assigned, which would make the finishing times similar for all but the most pathological cases (which would be indicated as one of those few &quot;you need an index rebuild&quot; cases.)

Size X would default to the size of hash that could be held in memory routinely, and might be something you could tune or a hint could be applied to the constraint enablement to use the special procedure instead of standard set aggregation code. Sigh.

I too never tested this. Thanks for quickly addressing this issue. Once again the hallmark of an actual expert is to publicly and cogently correct any discovered error. And you&#039;ve gone on in great depth depict the actual lay of the land.

Nice work, my friend.]]></description>
		<content:encoded><![CDATA[<p>Interesting study indeed!</p>
<p>I *hope* it leads to Oracle performing pk constraint validations explicitly by treewalk(not fast) full index scan when over size X. Where you only have to keep 1 previous value (and the start of the next section if parallel) in memory per parallel thread, and even with exception tracking only the duplicates need to get written. Parallel scan points could be picked from the starting node and a thread finishing would pick up a point not yet assigned, which would make the finishing times similar for all but the most pathological cases (which would be indicated as one of those few &#8220;you need an index rebuild&#8221; cases.)</p>
<p>Size X would default to the size of hash that could be held in memory routinely, and might be something you could tune or a hint could be applied to the constraint enablement to use the special procedure instead of standard set aggregation code. Sigh.</p>
<p>I too never tested this. Thanks for quickly addressing this issue. Once again the hallmark of an actual expert is to publicly and cogently correct any discovered error. And you&#8217;ve gone on in great depth depict the actual lay of the land.</p>
<p>Nice work, my friend.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
