<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-26949436</id><updated>2012-01-09T15:31:54.569-08:00</updated><title type='text'>SimonK's Oracle Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://skdba.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://skdba.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Simon Kelsey</name><uri>http://www.blogger.com/profile/03274506301447513043</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-26949436.post-115626177584256831</id><published>2006-08-22T08:33:00.000-07:00</published><updated>2006-08-22T08:52:28.333-07:00</updated><title type='text'>10053 to the rescue again!</title><content type='html'>I had a curious incident the other day.  I had two databases, each containing an identical copy of a table.  Previously, queries referencing the table in one database had run in the same time as queries referencing the table in the other database.  Now, however, one of the databases ran the query painfully slowly.&lt;br /&gt;&lt;br /&gt;When I took a look, the execution plans for the queries were not the same, so Of course, the first place I looked was in the statistics.  What I found was quite interesting - the "fast" table had been analyzed with a sample of 10%, whereas the "slow" table had been analyzed 100%.  When I re-analyzed the table with a 10% sample size, hey presto the original (fast) plan was once again chosen.&lt;br /&gt;&lt;br /&gt;So I started taking a look at HOW the CBO had come up with the respective plans, and I did this with a 10053 trace.  (Although the query was quite complicated, I've simplified it right down in this post, for clarity.)  What I'll do here is explain first what the problem was, and then show how it affected the decision of the CBO...&lt;br /&gt;&lt;br /&gt;The problem was that in the million row table, there was one row which had an incorrect value.  It was a date of 13-JUL-8569.  It was just wrong.  Very wrong.  There shouldn't have been anything higher than SYSDATE plus about a month.  Here's what I saw (table and column names changed to protect the innocent!):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; select to_char(max(my_date),'DD-MON-YYYY HH24:MI:SS') from my_table;&lt;br /&gt;&lt;br /&gt;TO_CHAR(MAX(MY_DATE)&lt;br /&gt;--------------------&lt;br /&gt;13-JUL-8569 00:00:00&lt;br /&gt;&lt;br /&gt;SQL&gt; select to_char(min(my_date),'DD-MON-YYYY HH24:MI:SS') from my_table;&lt;br /&gt;&lt;br /&gt;TO_CHAR(MIN(MY_DATE)&lt;br /&gt;--------------------&lt;br /&gt;03-JUL-1996 00:00:00&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;My_table has an index on my_date.&lt;br /&gt;&lt;br /&gt;In the query we had the predicate WHERE my_date &amp;LT SYSDATE.  So without a histogram, the optimizer was assuming a uniform distribution of dates between 1996 and 8569, meaning that the likelihood of a date being &amp;LT SYSDATE was pretty small.  In fact, without this bad date, the range would be between 1996 and SYSDATE+30, meaning that the likelihood of a date being &amp;LT SYSDATE was extremely high.&lt;br /&gt;&lt;br /&gt;What had happened was that in sampling at 10%, we had not sampled the bad date, and hence calculated a sensible cardinality, but as soon as we sampled 100% we included the bad date and the cardinality was stupidly low.  (Needless to say, the solution was to fix the bad data rather than to gamble on the sample missing it!)&lt;br /&gt;&lt;br /&gt;To illustrate this I have recreated a simplified version below.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; create table my_table&lt;br /&gt;  2  (my_date date, my_char char(100) );&lt;br /&gt;&lt;br /&gt;Table created.&lt;br /&gt;&lt;br /&gt;SQL&gt; begin&lt;br /&gt;  2  for i in 1 .. 10000 loop&lt;br /&gt;  3  insert into my_table values (sysdate-dbms_random.value(1,1000), 'X');&lt;br /&gt;  4  end loop;&lt;br /&gt;  5  commit;&lt;br /&gt;  6  end;&lt;br /&gt;  7  /&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;SQL&gt; create index test1_n1 on my_table(my_date);&lt;br /&gt;&lt;br /&gt;Index created.&lt;br /&gt;&lt;br /&gt;SQL&gt; exec dbms_stats.gather_table_stats(ownname=&gt;'SYS',tabname=&gt;'MY_TABLE',cascade=&gt;true);&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;SQL&gt; update my_table set my_date=sysdate+1000000 where rownum=1;&lt;br /&gt;&lt;br /&gt;1 row updated.&lt;br /&gt;&lt;br /&gt;SQL&gt; commit;&lt;br /&gt;&lt;br /&gt;Commit complete.&lt;br /&gt;&lt;br /&gt;SQL&gt; set autotrace on&lt;br /&gt;SQL&gt; select * from my_table where my_date&lt;sysdate;&lt;br /&gt;&lt;br /&gt;&amp;LTsome editing here, but not of anything relevant&amp;GT&lt;br /&gt;&lt;br /&gt;Execution Plan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=38 Card=10000 Bytes=&lt;br /&gt;          1090000)&lt;br /&gt;&lt;br /&gt;   1    0   TABLE ACCESS (FULL) OF 'MY_TABLE' (Cost=38 Card=10000 Byte&lt;br /&gt;          s=1090000)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;       831  consistent gets&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;SQL&gt; exec dbms_stats.gather_table_stats(ownname=&gt;'SYS',tabname=&gt;'MY_TABLE',cascade=&gt;true);&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;SQL&gt; select * from my_table where my_date &amp;LT sysdate;&lt;br /&gt;&lt;br /&gt;&amp;LTsome editing here, but not of anything relevant&amp;GT&lt;br /&gt;&lt;br /&gt;Execution Plan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=13 Card=10 Bytes=109&lt;br /&gt;          0)&lt;br /&gt;&lt;br /&gt;   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'MY_TABLE' (Cost=13 Card=&lt;br /&gt;          10 Bytes=1090)&lt;br /&gt;&lt;br /&gt;   2    1     INDEX (RANGE SCAN) OF 'TEST1_N1' (NON-UNIQUE) (Cost=3 Ca&lt;br /&gt;          rd=10)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      10631  consistent gets&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;So you can see that the index range scan looks preferable when the bad data is analyzed.  The operation is assigned a falsely low cost, and you can see the far greater number of consistent gets required.&lt;br /&gt;&lt;br /&gt;As I mentioned, the original query was a quite complicated, and involved joining several tables, so when I started looking at the problem, it wasn't quite a "needle in a haystack" but it was, shall we say, not obvious.  It was the 10053 trace which led me to find the cause of the problem.  I did this as follows:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; alter session set events '10053 trace name context forever, level 1';&lt;br /&gt;&lt;br /&gt;Session altered.&lt;br /&gt;&lt;br /&gt;SQL&gt; explain plan for select * from my_table where my_date &amp;LTsysdate;&lt;br /&gt;&lt;br /&gt;Explained.&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;The trace files were in my udump directory, and this is what I saw:&lt;br /&gt;&lt;br /&gt;When bad data excluded, query runs fast using Full Table Scan -&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;SINGLE TABLE ACCESS PATH&lt;br /&gt;Column:    MY_DATE  Col#: 1      Table: MY_TABLE   Alias: MY_TABLE&lt;br /&gt;    NDV: 10000     NULLS: 0         DENS: 1.0000e-04 LO:  2452971  HI: 2453970&lt;br /&gt;    NO HISTOGRAM: #BKT: 1 #VAL: 2&lt;br /&gt;  TABLE: MY_TABLE     ORIG CDN: 10000  ROUNDED CDN: 10000  CMPTD CDN: 10000&lt;br /&gt;  Access path: tsc  Resc:  38  Resp:  37&lt;br /&gt;  Access path: index (scan)&lt;br /&gt;      Index: TEST1_N1&lt;br /&gt;  TABLE: MY_TABLE&lt;br /&gt;      RSC_CPU: 74650907   RSC_IO: 9963&lt;br /&gt;  IX_SEL:  1.0000e+00  TB_SEL:  1.0000e+00&lt;br /&gt;  BEST_CST: 38.00  PATH: 2  Degree:  1&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;.&lt;br /&gt;When bad data included, query runs slowly using Index Range Scan -&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;SINGLE TABLE ACCESS PATH&lt;br /&gt;Column:    MY_DATE  Col#: 1      Table: MY_TABLE   Alias: MY_TABLE&lt;br /&gt;    NDV: 10000     NULLS: 0         DENS: 1.0000e-04 LO:  2452971  HI: 3453971&lt;br /&gt;    NO HISTOGRAM: #BKT: 1 #VAL: 2&lt;br /&gt;  TABLE: MY_TABLE     ORIG CDN: 10000  ROUNDED CDN: 10  CMPTD CDN: 10&lt;br /&gt;  Access path: tsc  Resc:  38  Resp:  37&lt;br /&gt;  Access path: index (scan)&lt;br /&gt;      Index: TEST1_N1&lt;br /&gt;  TABLE: MY_TABLE&lt;br /&gt;      RSC_CPU: 89153   RSC_IO: 12&lt;br /&gt;  IX_SEL:  9.9883e-04  TB_SEL:  9.9883e-04&lt;br /&gt;  BEST_CST: 13.00  PATH: 4  Degree:  1&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;.&lt;br /&gt;Here you can see here the falsely low computed cardinality, which in the case of the predicate I used, is NUM_ROWS * (value-low / high-low).&lt;br /&gt;&lt;br /&gt;I don't propose to reproduce it all here, but the paper by Wolfgang Breitling entitled &lt;a href=http://www.centrexcc.com/A%20Look%20under%20the%20Hood%20of%20CBO%20-%20the%2010053%20Event.pdf&gt;"A look under the hood of CBO"&lt;/a&gt; is a good place to start reading up on this stuff if you are not familiar, and of course you can't discuss this without mentioning Jonathan Lewis' excellent &lt;a href=http://www.jlcomp.demon.co.uk/cbo_book/ind_book.html&gt;"Cost Based Oracle Fundamentals"&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/26949436-115626177584256831?l=skdba.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://skdba.blogspot.com/feeds/115626177584256831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=26949436&amp;postID=115626177584256831' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/115626177584256831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/115626177584256831'/><link rel='alternate' type='text/html' href='http://skdba.blogspot.com/2006/08/10053-to-rescue-again.html' title='10053 to the rescue again!'/><author><name>Simon Kelsey</name><uri>http://www.blogger.com/profile/03274506301447513043</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-26949436.post-115400711090394062</id><published>2006-07-27T06:13:00.000-07:00</published><updated>2006-07-27T06:31:50.943-07:00</updated><title type='text'>We do not use...</title><content type='html'>I'm so excited, I just did my first ever "we do not use".  I am forever indebted to Mogens for introducing me to this concept; for the uninitiated, please see &lt;a href="http://www.wedonotuse.com/"&gt;www.wedonotuse.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It was a relatively straightforward "we do not use" scenario, but I was astonished at the ease with which I was able to end an unwanted sales call whilst retaining utmost politesse.&lt;br /&gt;&lt;br /&gt;It related simply to a magazine subscription, to which I replied "thank you but we do not use magazines" - and that was it!  End of call!  Thanks Mogens.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/26949436-115400711090394062?l=skdba.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://skdba.blogspot.com/feeds/115400711090394062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=26949436&amp;postID=115400711090394062' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/115400711090394062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/115400711090394062'/><link rel='alternate' type='text/html' href='http://skdba.blogspot.com/2006/07/we-do-not-use.html' title='We do not use...'/><author><name>Simon Kelsey</name><uri>http://www.blogger.com/profile/03274506301447513043</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-26949436.post-115347841164572660</id><published>2006-07-21T02:57:00.000-07:00</published><updated>2006-07-21T03:40:11.703-07:00</updated><title type='text'>Parallel DML / Controlfile Lock</title><content type='html'>The other day one of my production databases experienced a problem... Everything was fine until suddenly an XA transaction timed out and rolled back, holding a lock that a bunch of other sessions wanted to acquire, and causing them to time out and roll back too.&lt;br /&gt;&lt;br /&gt;The database was behaving normally, it's just that something happened to make a transaction take fractionally longer than the application designers had specified.  Of course, my job was to find out what that "something" was.&lt;br /&gt;&lt;br /&gt;It's a complex architecture, and there were many places where the problem could have been - in the network, the middleware, the database, etc.  Fingers were pointing at the database, and in my usual style I defended Oracle to the hilt.  However, I needed to look into it just to prove it wasn't a database problem (sadly it turned out it was!)&lt;br /&gt;&lt;br /&gt;In the initial investigation, application support had run the following script, which joins v$lock and v$session to show blocking and waiting sessions.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;SELECT   bs.username "Blocking User",&lt;br /&gt;  bs.username "DB User",&lt;br /&gt;         ws.username "Waiting User",&lt;br /&gt;  bs.sid "SID",&lt;br /&gt;  ws.sid "WSID",&lt;br /&gt;         bs.sql_address "address",&lt;br /&gt;  bs.sql_hash_value "Sql hash",&lt;br /&gt;         bs.program "Blocking App",&lt;br /&gt;  ws.program "Waiting App",&lt;br /&gt;         bs.machine "Blocking Machine",&lt;br /&gt;  ws.machine "Waiting Machine",&lt;br /&gt;         bs.osuser "Blocking OS User",&lt;br /&gt;  ws.osuser "Waiting OS User",&lt;br /&gt;         bs.serial# "Serial#",&lt;br /&gt;         DECODE (&lt;br /&gt;            wk.TYPE,&lt;br /&gt;            'MR', 'Media Recovery',&lt;br /&gt;            'RT', 'Redo Thread',&lt;br /&gt;            'UN', 'USER Name',&lt;br /&gt;            'TX', 'Transaction',&lt;br /&gt;            'TM', 'DML',&lt;br /&gt;            'UL', 'PL/SQL USER LOCK',&lt;br /&gt;            'DX', 'Distributed Xaction',&lt;br /&gt;            'CF', 'Control FILE',&lt;br /&gt;            'IS', 'Instance State',&lt;br /&gt;            'FS', 'FILE SET',&lt;br /&gt;            'IR', 'Instance Recovery',&lt;br /&gt;            'ST', 'Disk SPACE Transaction',&lt;br /&gt;            'TS', 'Temp Segment',&lt;br /&gt;            'IV', 'Library Cache Invalidation',&lt;br /&gt;            'LS', 'LOG START OR Switch',&lt;br /&gt;            'RW', 'ROW Wait',&lt;br /&gt;            'SQ', 'Sequence Number',&lt;br /&gt;            'TE', 'Extend TABLE',&lt;br /&gt;            'TT', 'Temp TABLE',&lt;br /&gt;            wk.TYPE&lt;br /&gt;         ) lock_type,&lt;br /&gt;         DECODE (&lt;br /&gt;            hk.lmode,&lt;br /&gt;            0, 'None',&lt;br /&gt;            1, 'NULL',&lt;br /&gt;            2, 'ROW-S (SS)',&lt;br /&gt;            3, 'ROW-X (SX)',&lt;br /&gt;            4, 'SHARE',&lt;br /&gt;            5, 'S/ROW-X (SSX)',&lt;br /&gt;            6, 'EXCLUSIVE',&lt;br /&gt;            TO_CHAR (hk.lmode)&lt;br /&gt;         ) mode_held,&lt;br /&gt;         DECODE (&lt;br /&gt;            wk.request,&lt;br /&gt;            0, 'None',&lt;br /&gt;            1, 'NULL',&lt;br /&gt;            2, 'ROW-S (SS)',&lt;br /&gt;            3, 'ROW-X (SX)',&lt;br /&gt;            4, 'SHARE',&lt;br /&gt;            5, 'S/ROW-X (SSX)',&lt;br /&gt;            6, 'EXCLUSIVE',&lt;br /&gt;            TO_CHAR (wk.request)&lt;br /&gt;         ) mode_requested,&lt;br /&gt;         TO_CHAR (hk.id1) lock_id1,&lt;br /&gt;  TO_CHAR (hk.id2) lock_id2&lt;br /&gt;    FROM v$lock hk,&lt;br /&gt;  v$session bs,&lt;br /&gt;  v$lock wk,&lt;br /&gt;  v$session ws&lt;br /&gt;   WHERE hk.BLOCK = 1&lt;br /&gt;     AND hk.lmode != 0&lt;br /&gt;     AND hk.lmode != 1&lt;br /&gt;     AND wk.request != 0&lt;br /&gt;     AND wk.TYPE(+) = hk.TYPE&lt;br /&gt;     AND wk.id1(+) = hk.id1&lt;br /&gt;     AND wk.id2(+) = hk.id2&lt;br /&gt;     AND hk.sid = bs.sid(+)&lt;br /&gt;     AND wk.sid = ws.sid(+)&lt;br /&gt;ORDER BY 1;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;.&lt;br /&gt;Whilst clutching at straws, they noted that in addition to the one blocking session and all the waiting sessions, there were also the following two rows, (which I've edited here):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;BLOCKING_USER           WAITING_USER            LOCK_TYPE       MODE_HELD  MODE_REQUESTED&lt;br /&gt;-------------           ------------            ---------       ---------  --------------&lt;br /&gt;oracle@foobar (CKPT)    oracle@foobar   (ARC1)  Control FILE    EXCLUSIVE  EXCLUSIVE&lt;br /&gt;oracle@foobar (CKPT)    oracle@foobar   (P011)  Control FILE    EXCLUSIVE  SHARE&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;.&lt;br /&gt;The question asked of me was, was it the checkpoint which caused the problem?  I dismissed this idea quickly, but needed to give some evidence.  No big surprises that a checkpoint holds an exclusive CF lock, nor was I concerned that the Archiver process was waiting its turn.  But I was interested in that parallel process...&lt;br /&gt;&lt;br /&gt;Given I know that nothing within the application should go parallel until the batch kicks in overnight, my suspicions turned to "ad hoc" activity rather than the application - it looked at bit like someone was poking about when they shouldn't have been... or something was going parallel when it shouldn't - it wouldn't be the first time a segment accidentally had a degree of "DEFAULT" or &gt;1.&lt;br /&gt;&lt;br /&gt;But why would it be wanting a controlfile lock?  I started thinking about something like a nologging CTAS, which would need to update the unrecoverable scn in the controlfile for the datafile in question.  But then again, if it was parallel DML doing direct i/o then there would need to be a Segment Level Checkpoint anyway, hence the need to access the controlfile.&lt;br /&gt;&lt;br /&gt;A quick look at a statspack report for the time in question revealed all - it wasn't the application, it was someone connecting via sqlplus, and it was indeed a parallel CTAS.  The controlfile lock had absolutely nothing to do with the original problem, but the sudden burst of activity to do a (relatively big) paralel CTAS was enough to make the database just unresponsive enough for the middleware to time a transaction out...&lt;br /&gt;&lt;br /&gt;So ironically it was the CF lock held by CKPT which led me to look at what was using parallelism, which led me to the answer which was nothing to do with the CF lock!  Still, it kept me busy for a while.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/26949436-115347841164572660?l=skdba.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://skdba.blogspot.com/feeds/115347841164572660/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=26949436&amp;postID=115347841164572660' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/115347841164572660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/115347841164572660'/><link rel='alternate' type='text/html' href='http://skdba.blogspot.com/2006/07/parallel-dml-controlfile-lock.html' title='Parallel DML / Controlfile Lock'/><author><name>Simon Kelsey</name><uri>http://www.blogger.com/profile/03274506301447513043</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-26949436.post-115168344763082530</id><published>2006-06-30T08:24:00.000-07:00</published><updated>2006-07-04T01:32:53.156-07:00</updated><title type='text'>Keeping a history of CBO Stats</title><content type='html'>Whilst working with Doug Burns on CBO Stats history, the thing he blogs about &lt;a href="http://oracledoug.com/serendipity/index.php?/archives/1000-Saving-Optimiser-Stats-10g.html" &gt;here&lt;/a&gt;, I cobbled together a procedure which would compare one set of saved stats with another set, and tell you exactly what had changed.&lt;br /&gt;&lt;br /&gt;However, bearing in mind the "stattab" you use wasn't really designed to be queried in this way, I couldn't find much (anything) in the way of documentation on what the columns represent - so I had to just poke about and try to find out myself.&lt;br /&gt;&lt;br /&gt;[Please note - the info below relates to version 9.2.0.7.  I haven't looked into how version specific this is...]&lt;br /&gt;&lt;br /&gt;A given column in the stattab has a different use depending on the kind of statistics.  For example, for a TABLE, the column N3 represents AVG_ROW_LEN, whereas for an index, the same column N3 represents DISTINCT_KEYS.&lt;br /&gt;&lt;br /&gt;Here is my list, for TABLE, INDEX and COLUMN stats, of what I think the stattab columns represent.  I couldn't work out what the column N3 represents when dealing with column stats.  If anyone knows, I'd me very interested to hear, please post a comment.  Likewise any errors or omissions, anything you disagree with.&lt;br /&gt;&lt;br /&gt;Here it is:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;STATID   User defined stat id&lt;br /&gt;&lt;br /&gt;TYPE     T=Table      I=Index                    C=Column&lt;br /&gt;C1       Table_Name   Index_Name                 Table_Name&lt;br /&gt;C2       Null         Null                       Null&lt;br /&gt;C3       Null         Null                       Null&lt;br /&gt;C4       Null         Null                       Column_Name&lt;br /&gt;C5       Owner        Owner                      Owner&lt;br /&gt;N1       Num_Rows     Num_Rows                   Num_distinct&lt;br /&gt;N2       Blocks       Leaf_Blocks                Density&lt;br /&gt;N3       Avg_Row_Len  Distinct_Keys              ????????&lt;br /&gt;N4       Sample_Size  Avg_Leaf_Blocks_per_key    Sample_Size&lt;br /&gt;N5       Null         Avg_Data_Blocks_per_key    Num_Nulls&lt;br /&gt;N6       Null         Clustering_Factor          First Endpoint_Value&lt;br /&gt;N7       Null         Blevel                     Last Endpoint_Value&lt;br /&gt;N8       Null         Sample_Size                Avg_Col_Len&lt;br /&gt;N9       Null         pct_direct_access          Histogram Flag&lt;br /&gt;N10      Null         Null                       Endpoint_Number&lt;br /&gt;N11      Null         Null                       Endpoint_Value&lt;br /&gt;N12      Null         Null                       Null&lt;br /&gt;R1       Null         Null                       High_Value&lt;br /&gt;R2       Null         Null                       Low_value&lt;br /&gt;CH1      Null         Null                       Endpoint_Actual_Value&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/26949436-115168344763082530?l=skdba.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://skdba.blogspot.com/feeds/115168344763082530/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=26949436&amp;postID=115168344763082530' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/115168344763082530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/115168344763082530'/><link rel='alternate' type='text/html' href='http://skdba.blogspot.com/2006/06/keeping-history-of-cbo-stats.html' title='Keeping a history of CBO Stats'/><author><name>Simon Kelsey</name><uri>http://www.blogger.com/profile/03274506301447513043</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-26949436.post-115027894123563359</id><published>2006-06-14T02:54:00.000-07:00</published><updated>2006-06-14T02:55:41.243-07:00</updated><title type='text'>A Dirty Read.</title><content type='html'>I had the misfortune to have to deal with a problem on an Informix database yesterday.  The problem was to do with row-level locking, where a row was locked by a query.  With my totally Oracle background, I was a little shaken by this, i.e queries needing to lock rows.  (That, and the fact that you can roll back DDL!  That kind of threw me for a moment, but now I understand why some folks get a bit uncomfortable with the fact that you can't do this with Oracle!)&lt;br /&gt;&lt;br /&gt;So anyway, after introducing the developer to the concept of a dirty read, (in the nicest possible sense), there then followed a discussion between the DBAs I work with about just HOW COOL oracle's locking mechanisms are.  Clearly this puts us way into the "geek" bracket, talking about locking mechanisms instead of the World Cup, but I got Equador in the office sweepstake, so I can kiss my fiver goodbye.&lt;br /&gt;&lt;br /&gt;You kind of take it for granted that if you update a million rows the commit won't take an age, but when you stop to consider why, you have to say it's quite a good design.  Instead of using lock tables, the lock is registered in the row header, and the transaction in the ITL in the block header, so you can never run out of locks...  And when it comes to releasing the locks,  if DBWR (sorry, DBWn) has already written the block, then you just wait for it to be used again, and then determine whether the transaction committed or not.  Quite slick.&lt;br /&gt;&lt;br /&gt;OK, so you have the problem of determining the commit SCN, so that when you perform a consistent get you know which image of the block to use.  What if it's not in the rollback segment header any more?  Not a problem, because you don't need to know exactly when the transaction committed, just whether it committed before your snapshot SCN or not.&lt;br /&gt;&lt;br /&gt;Still, I guess it doesn't come for free, the price we pay is having to deal with the whole rollback segments thing, although Automatic Undo Management has taken some of the fun out of this.&lt;br /&gt;&lt;br /&gt;We all still love the opportunity of diagnosing ORA-01555 errors, and don't let anyone try to tell you they don't happen any more with AUM - I've seen enough.  To be fair, though, mostly due to inappropriate undo retention, so not a really tricky one.  Of course, people will still insist on fetching across commits, and some will look at you strangely if you suggest committing LESS frequently, but there we are.  All part of the fun.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/26949436-115027894123563359?l=skdba.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://skdba.blogspot.com/feeds/115027894123563359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=26949436&amp;postID=115027894123563359' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/115027894123563359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/115027894123563359'/><link rel='alternate' type='text/html' href='http://skdba.blogspot.com/2006/06/dirty-read.html' title='A Dirty Read.'/><author><name>Simon Kelsey</name><uri>http://www.blogger.com/profile/03274506301447513043</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-26949436.post-114838723584463676</id><published>2006-05-23T04:55:00.000-07:00</published><updated>2006-05-23T05:27:15.873-07:00</updated><title type='text'>Compression and my Oracle OCD</title><content type='html'>I've been poking around with segment compression lately. I started looking into it whilst preparing my presentation for the Scotland OUG meeting, but now I've started playing with it, I can't stop. I want to know a little bit more every time, it's like an obsessive compulsion. I should probably seek help.&lt;br /&gt;&lt;br /&gt;I hadn't realized that columns of length less than 6 don't get compressed, (until I read something Geoff Moss had written on the subject), so I just wanted to prove it to myself. So I created a table with one column, VARCHAR2(5), and populated it with 4194304 rows each containing 'XXXXX'.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;SQL&gt; alter table test1 move;&lt;br /&gt;&lt;br /&gt;Table altered.&lt;br /&gt;&lt;br /&gt;SQL&gt; select bytes/1048576 meg, blocks from dba_segments where segment_name='TEST1';&lt;br /&gt;&lt;br /&gt;       MEG     BLOCKS&lt;br /&gt;---------- ----------&lt;br /&gt;  49.84375       6380&lt;br /&gt;&lt;br /&gt;SQL&gt; alter table test1 move compress;&lt;br /&gt;&lt;br /&gt;Table altered.&lt;br /&gt;&lt;br /&gt;SQL&gt; select bytes/1048576 meg, blocks from dba_segments where segment_name='TEST1';&lt;br /&gt;&lt;br /&gt;       MEG     BLOCKS&lt;br /&gt;---------- ----------&lt;br /&gt; 44.859375       5742&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Eh?  What?  I though the columns weren't supposed to be compressed?&lt;br /&gt;Why's it smaller?  What happened?&lt;br /&gt;A fraction of a second later I remembered that altering a table "compress" also has the effect of setting pct_free to zero (it had previously been 10). And yes, the original 6380 blocks are now 638 fewer. The attempted compression did not compress anything.&lt;br /&gt;&lt;br /&gt;Pretty obvious, but note that altering a table back to nocompress still leaves pct_free as zero. I mean, it would, wouldn't it.&lt;br /&gt;&lt;br /&gt;When I did the same thing with a VARCHAR2(6) I did indeed get the compression I expected (not fantastic - the longer the column the more benefit, so I expected a poor compression ratio). My table went from 6266 blocks to 5758.&lt;br /&gt;&lt;br /&gt;Now I want to see what the reason is for the 6 byte limit. Logically it must simply be that the reference to the value in the symbol table becomes longer that the original data, but given my Oracle Obsessive Compulsive Disorder I am now have to poke about with dumping blocks and look at the internal structure of the symbol table, compressed row data and so on, and so on. Not sure how I'll get on with that, but I'll keep you posted.&lt;br /&gt;&lt;br /&gt;My apologies to anyone who stumbled upon this post looking for information about Oracle Configurator Developer, by the way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/26949436-114838723584463676?l=skdba.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://skdba.blogspot.com/feeds/114838723584463676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=26949436&amp;postID=114838723584463676' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/114838723584463676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/114838723584463676'/><link rel='alternate' type='text/html' href='http://skdba.blogspot.com/2006/05/compression-and-my-oracle-ocd.html' title='Compression and my Oracle OCD'/><author><name>Simon Kelsey</name><uri>http://www.blogger.com/profile/03274506301447513043</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-26949436.post-114725271447068642</id><published>2006-05-10T02:03:00.000-07:00</published><updated>2006-05-10T02:18:34.476-07:00</updated><title type='text'>Relieved it's over!</title><content type='html'>I was stressing out quite a lot about presenting at the OUG Scotland event - never having done anything like that before. It didn't help that &lt;a href="http://oracledoug.blogspot.com/"&gt;Doug Burns&lt;/a&gt; was winding me up very effectively at every possible opportunity ;-) It was he who talked me into presenting in the first place, and I think he took great delight in seeing me panicing as the date drew closer!&lt;br /&gt;&lt;br /&gt;Seriously though, thanks to Doug, and Peter Robson for their encouragement and support, it was nervewracking to do, but I'm glad I did it.  Feedback from the floor was positive (or were people just being kind?!), and will definitely spur me on to do it again - stuff like "thanks, I learned something today from your presentation" which is all I could have hoped for.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/26949436-114725271447068642?l=skdba.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://skdba.blogspot.com/feeds/114725271447068642/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=26949436&amp;postID=114725271447068642' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/114725271447068642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/114725271447068642'/><link rel='alternate' type='text/html' href='http://skdba.blogspot.com/2006/05/relieved-its-over.html' title='Relieved it&apos;s over!'/><author><name>Simon Kelsey</name><uri>http://www.blogger.com/profile/03274506301447513043</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-26949436.post-114708232832296201</id><published>2006-05-08T02:45:00.000-07:00</published><updated>2006-05-08T02:58:48.330-07:00</updated><title type='text'>OUG Scotland</title><content type='html'>Looking forward to the UKOUG event in Edinburgh tomorrow.  I've been "roped in" to giving a presentation, and I must say, although I'm looking forward to it, it's the first time I've done anything like that and I'm rather nervous.  Especially given the other speakers, all of whom are highly experienced, highly respected members of the Oracle community.&lt;br /&gt;&lt;br /&gt;I was looking at data compression for some data warehouse data and also for some historic partitioned data which needed kept online for regulatory reasons but would scarcely be queried, never mind modified.  So when I was asked to speak at the UKOUG event I though "fine, I'll talk about Data Compression".  It was only when I was most of the way through putting my presentation together that I found a bunch of other presentations on the knocking around on the web on the same topic.  So I hope I'm not going to bore my audience with stuff they already know...  Looks like the subject has already received a lot of attention.  Oh well... always room for one more.&lt;br /&gt;&lt;br /&gt;I'm going to keep the presentation really simple - it's not a Paper after all.  So I'm just going to explain the basic concepts and show some results of some testing I did, and the conclusions I drew.  I hope it goes down OK - if you are attending, don't give me a hard time!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/26949436-114708232832296201?l=skdba.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://skdba.blogspot.com/feeds/114708232832296201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=26949436&amp;postID=114708232832296201' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/114708232832296201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/114708232832296201'/><link rel='alternate' type='text/html' href='http://skdba.blogspot.com/2006/05/oug-scotland.html' title='OUG Scotland'/><author><name>Simon Kelsey</name><uri>http://www.blogger.com/profile/03274506301447513043</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-26949436.post-114648119316273710</id><published>2006-05-01T03:53:00.000-07:00</published><updated>2006-05-08T02:44:52.006-07:00</updated><title type='text'>First Steps</title><content type='html'>Bear with me. I appreciate that if this posting is successful it will be pitifully dull to read, but I'm still getting things sorted out with this new blog, and I'm really only posting this to "see what happens"...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/26949436-114648119316273710?l=skdba.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://skdba.blogspot.com/feeds/114648119316273710/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=26949436&amp;postID=114648119316273710' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/114648119316273710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/114648119316273710'/><link rel='alternate' type='text/html' href='http://skdba.blogspot.com/2006/05/first-steps.html' title='First Steps'/><author><name>Simon Kelsey</name><uri>http://www.blogger.com/profile/03274506301447513043</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-26949436.post-114598076256685429</id><published>2006-04-25T08:39:00.000-07:00</published><updated>2006-04-25T08:59:22.573-07:00</updated><title type='text'>Another Oracle Blog Is Born</title><content type='html'>My name is Simon Kelsey and I've been working with Oracle databases for about 14 years now.  I'm new to this whole blogging thing, but I have been pursuaded by a fellow DBA and keen blogger that I should start a blog and record for the community anything of interest that I come across.&lt;br /&gt;&lt;br /&gt;I'm not sure how this is going to go, but I'm pretty hopeful I'll have at least a few things to share.  I'm going to leave this initial post on whilst I set up some other bits and pieces, and then I'll start in earnest...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/26949436-114598076256685429?l=skdba.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://skdba.blogspot.com/feeds/114598076256685429/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=26949436&amp;postID=114598076256685429' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/114598076256685429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/26949436/posts/default/114598076256685429'/><link rel='alternate' type='text/html' href='http://skdba.blogspot.com/2006/04/another-oracle-blog-is-born.html' title='Another Oracle Blog Is Born'/><author><name>Simon Kelsey</name><uri>http://www.blogger.com/profile/03274506301447513043</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
