<?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-8612611874818330035</id><updated>2012-01-18T10:57:19.710-08:00</updated><category term='instrument'/><category term='histogram'/><category term='Oracle DBA'/><category term='undo'/><category term='standby'/><category term='Analytic'/><category term='10053 trace'/><category term='SQL'/><category term='CBO'/><category term='asynchronous process'/><category term='selectivity'/><category term='ADT'/><category term='PL/SQL'/><category term='benchmark'/><category term='passion creative life'/><category term='collection'/><category term='BASE'/><category term='Oracle'/><category term='DBA priority'/><category term='array'/><category term='test'/><category term='density'/><category term='hint'/><category term='consistency'/><category term='external table'/><category term='dbms_rowid extent'/><category term='html'/><category term='11g'/><category term='Database API'/><category term='partition'/><category term='dbms_xplan'/><category term='set based process'/><category term='split function'/><category term='work'/><category term='data guard'/><category term='generate'/><category term='compress'/><title type='text'>木匠的天空 Database Architect and Developer</title><subtitle type='html'>A man who has imagination has wings. 
The sky's the limit. 
DBA + data modeler + developer</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>45</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-2369125671140355385</id><published>2011-06-07T14:31:00.000-07:00</published><updated>2011-06-07T16:40:03.396-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>Question to AskTom on Oracle Magazine</title><content type='html'>Just threw a random question to Tom after read his column in Oracle Magazine, to my surprise, Tom replied, and it made me happy for a couple weeks.&lt;br /&gt;AskTom link &lt;a href="http://www.oracle.com/technetwork/issue-archive/2011/11-may/o31asktom-354139.html"&gt;www.oracle.com/technetwork/issue-archive/2011/11-may/o31asktom-354139.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;My question to Tom,&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #0b5394;"&gt;Just read you Q&amp;amp;A on "Bulking Up" on May 2011 Oracle Magazine.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #0b5394;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #0b5394;"&gt;It looks like UPDATE is different than INSERT when comparing PL/SQL BULK to single SQL.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #0b5394;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #0b5394;"&gt;Single SQL INSERT is about same as BULK INSERT when comparing the resource usage,&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #0b5394;"&gt;But based on your benchmark, Single SQL UPDATE is way more better than array bulk UPDATE.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #0b5394;"&gt;I'll build a test case and run benchmark of UPDATE myself and blog it later.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #0b5394;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #0b5394;"&gt;FYI, single SQL INSERT vs. array BULK INSERT.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #0b5394;"&gt;&lt;a href="http://mujiang.blogspot.com/2009/06/single-insert-vs-array-bulk-insert.html"&gt;http://mujiang.blogspot.com/2009/06/single-insert-vs-array-bulk-insert.html&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Replied by Tom, on 31-May-11 12:46 PM, opubedit wrote:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #990000;"&gt;Charlie,&lt;br /&gt;&lt;br /&gt;With the single insert,&amp;nbsp; you can easily use /*+ APPEND */ -  allowing for direct path load, basic compression (comes with enterprise  edition), and redo/undo generation being skipped.&lt;br /&gt;&lt;br /&gt;with the bulk insert -  until 11.2 - you cannot.&amp;nbsp; In 11.2 you can use the append_values hint to do the  direct path load, but then you have to size your batches very carefully (since  direct pathing never reuses existing space, you'll have "chunks of  data")&lt;br /&gt;&lt;br /&gt;Further, you show a measurable different in cpu/elapsed time even  without these other advantages.&lt;br /&gt;&lt;br /&gt;I will stick with my advice of "do it in  a single sql statement if you can, if not do it in as little procedural code as  possible".&amp;nbsp; Unless there is no way to do it in a single insert as select - there  should be NO procedural code whatsoever.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;My reply:&lt;br /&gt;&lt;br /&gt;&lt;div class="x_MsoNormal"&gt;&lt;span style="color: #1f497d; font-family: Calibri, sans-serif;"&gt;Hi  Tom,&lt;/span&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;span style="color: #1f497d; font-family: Calibri, sans-serif;"&gt;Thanks  for the reply. I implement your mantra all the time, I’m thrifty to develop  procedure code out of single SQL.&lt;/span&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;span style="color: #1f497d; font-family: Calibri, sans-serif;"&gt;Context  is the king.&lt;/span&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;span style="color: #1f497d; font-family: Calibri, sans-serif;"&gt;.  Our data process logic cannot be done in single SQL.&lt;/span&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;span style="color: #1f497d; font-family: Calibri, sans-serif;"&gt;&amp;nbsp;..  We will update different target table columns based different comparison  scenarios, with different source data,&lt;/span&gt;&lt;/div&gt;&lt;div class="x_MsoNormal" style="text-indent: 9pt;"&gt;&lt;span style="color: #1f497d; font-family: Calibri, sans-serif;"&gt;(I  asked a question on AskTom, about how to only update the columns with changed  value. &amp;nbsp;&lt;/span&gt;&lt;span style="color: #1f497d; font-family: Wingdings;"&gt;J&lt;/span&gt;&lt;span style="color: #1f497d; font-family: Calibri, sans-serif;"&gt;  &lt;/span&gt;&lt;/div&gt;&lt;div class="x_MsoNormal" style="text-indent: 9pt;"&gt;&lt;span style="color: #1f497d; font-family: Calibri, sans-serif;"&gt;&amp;nbsp;  e.g. 70% of source data only update book price or qty.&lt;/span&gt;&lt;/div&gt;&lt;div class="x_MsoNormal" style="text-indent: 9pt;"&gt;&lt;span style="color: #1f497d; font-family: Calibri, sans-serif;"&gt;&amp;nbsp;&amp;nbsp;it’s  one of the update scenario. )&lt;/span&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;span style="color: #1f497d; font-family: Calibri, sans-serif;"&gt;&amp;nbsp;..  We will insert intermediate processed data to many staging tables based the each  comparison scenarios,&lt;/span&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;span style="color: #1f497d; font-family: Calibri, sans-serif;"&gt;&amp;nbsp;..  I tried multi-table INSERT, it still couldn’t solve our problem.&lt;/span&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;span style="color: #1f497d; font-family: Calibri, sans-serif;"&gt;.  Our primary database is forced logging to support standby database.&lt;/span&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;span style="color: #1f497d; font-family: Calibri, sans-serif;"&gt;So,  I did a benchmark to see how the bulk INSERT can be worse. The bulk  UPDATE vs. single SQL UPDATE will be benchmarked too in near future.&lt;/span&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="x_MsoNormal"&gt;&lt;span style="color: #1f497d; font-family: Arial, sans-serif; font-size: 10pt;"&gt;Thanks,&lt;/span&gt;&lt;span style="color: #1f497d; font-family: Calibri, sans-serif; font-size: 11pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;span style="color: #1f497d; font-family: Arial, sans-serif; font-size: 10pt;"&gt;Charlie  &lt;/span&gt;&lt;span lang="ZH-CN" style="color: #1f497d; font-family: SimSun; font-size: 10pt;"&gt;木匠&lt;/span&gt;&lt;span style="color: #1f497d; font-family: Arial, sans-serif; font-size: 10pt;"&gt; |  &lt;/span&gt;&lt;span lang="EN-CA" style="color: #1f497d; font-family: Batang, serif; font-size: 10pt;"&gt;Data Solution Architect/Developer&lt;/span&gt;&lt;span style="color: #1f497d; font-family: Arial, sans-serif; font-size: 10pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;span style="color: #1f497d; font-family: 'Arial Narrow', sans-serif; font-size: 9pt;"&gt;-  simple is beautiful and please consider the environment before printing this  e-mail.&lt;/span&gt;&lt;/div&gt;&lt;div class="x_MsoNormal"&gt;&lt;span style="color: #1f497d; font-family: 'Arial Narrow', sans-serif; font-size: 9pt;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;blockquote type="cite"&gt;&lt;pre&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-2369125671140355385?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/2369125671140355385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=2369125671140355385' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/2369125671140355385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/2369125671140355385'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2011/06/question-to-asktom-in-oracle-magazine.html' title='Question to AskTom on Oracle Magazine'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-3723471778233460114</id><published>2011-05-10T15:39:00.000-07:00</published><updated>2011-05-10T15:39:14.207-07:00</updated><title type='text'>Explore MongoDB</title><content type='html'>Here we go,&lt;br /&gt;&lt;br /&gt;&lt;a href="http://mongly.com/tutorial/index"&gt;http://mongly.com/tutorial/index&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="teach" style="background-attachment: initial; background-clip: initial; background-color: #f5ffd6; background-image: initial; background-origin: initial; border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; cursor: default; font-family: verdana, arial; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px;"&gt;&lt;span style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;Bravo!&lt;/span&gt;&lt;/div&gt;&lt;div class="teach" style="background-attachment: initial; background-clip: initial; background-color: #f5ffd6; background-image: initial; background-origin: initial; border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; cursor: default; font-family: verdana, arial; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px;"&gt;&lt;span style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;Hopefully you learnt something about MongoDB and Unicorns&lt;/span&gt;&lt;/div&gt;&lt;div class="teach" style="background-attachment: initial; background-clip: initial; background-color: #f5ffd6; background-image: initial; background-origin: initial; border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; cursor: default; font-family: verdana, arial; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px;"&gt;&lt;span style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;There's a lot we didn't cover, like embedded documents, aggregation, indexes, management, etc&lt;/span&gt;&lt;/div&gt;&lt;div class="teach" style="background-attachment: initial; background-clip: initial; background-color: #f5ffd6; background-image: initial; background-origin: initial; border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; cursor: default; font-family: verdana, arial; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px;"&gt;&lt;span style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;But the idea was to help get you confortable with the basics&lt;/span&gt;&lt;/div&gt;&lt;div class="teach" style="background-attachment: initial; background-clip: initial; background-color: #f5ffd6; background-image: initial; background-origin: initial; border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; cursor: default; font-family: verdana, arial; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px;"&gt;&lt;span style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;Feel free to play around, insert new data, new combinations, and what not&lt;/span&gt;&lt;/div&gt;&lt;div class="teach" style="background-attachment: initial; background-clip: initial; background-color: #f5ffd6; background-image: initial; background-origin: initial; border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; cursor: default; font-family: verdana, arial; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px;"&gt;&lt;span style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;Or, better yet, head over to&amp;nbsp;&lt;a href="http://www.mongodb.org/downloads" style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; color: #666699; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;the mongodb download&lt;/a&gt;&amp;nbsp;page, grab the version for your OS and experiment on your local machine&lt;/span&gt;&lt;/div&gt;&lt;div class="teach" style="background-attachment: initial; background-clip: initial; background-color: #f5ffd6; background-image: initial; background-origin: initial; border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; cursor: default; font-family: verdana, arial; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px;"&gt;&lt;span style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;The precompiled binaries available for Linux, Windows and OS X make MongoDB extremely easy to get started with&lt;/span&gt;&lt;/div&gt;&lt;div class="teach" style="background-attachment: initial; background-clip: initial; background-color: #f5ffd6; background-image: initial; background-origin: initial; border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; cursor: default; font-family: verdana, arial; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px;"&gt;&lt;span style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;Don't forget to check out my&amp;nbsp;&lt;a href="http://openmymind.net/2011/3/28/The-Little-MongoDB-Book" style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; color: #666699; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" target="_blank"&gt;free MongoDB ebook&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="teach" style="background-attachment: initial; background-clip: initial; background-color: #f5ffd6; background-image: initial; background-origin: initial; border-bottom-style: solid; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; cursor: default; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px;"&gt;&lt;div style="font-family: verdana, arial;"&gt;&lt;span style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;You are now web scale&lt;/span&gt;&lt;/div&gt;&lt;span style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div id="history" style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; font-family: verdana, arial; height: 250px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div class="ok" style="background-attachment: initial; background-clip: initial; background-color: honeydew; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px;"&gt;&lt;span style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;span style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;db.unicorns.find()&lt;/span&gt;&lt;span class="time" style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; float: right; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id="results" style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; font-family: menlo, consolas, arial; height: 676px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 37px; overflow-x: auto; overflow-y: auto; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;table id="grid" style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-style: none; border-collapse: collapse; border-color: initial; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; border-width: initial; font-family: menlo, consolas, arial; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: relative;"&gt;&lt;thead style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(255, 255, 255)), to(rgb(238, 238, 238))); background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;tr style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;td style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;_id&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;name&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;loves&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;dob&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;weight&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;gender&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(224, 224, 224); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;vampires&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;tr style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;4dc9bbfbbc7a0515660052c8&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;Aurora&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;["carrot","grape"]&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;1991-01-25T13:14:00Z&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;450&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;f&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;43&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;4dc9bbfbbc7a0515660052cb&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;Solnara&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;["apple","carrot","chocolate"]&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;1985-07-05T02:01:00Z&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;550&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;f&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;80&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;4dc9bbfbbc7a0515660052cc&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;Ayna&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;["strawberry","lemon"]&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;1998-03-08T08:30:00Z&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;733&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;f&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;40&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;4dc9bbfbbc7a0515660052cf&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;Leia&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;["apple","watermelon"]&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;2001-10-09T14:53:00Z&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;601&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;f&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;33&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;4dc9bbfbbc7a0515660052d1&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;Nimue&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;["grape","carrot"]&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;1999-12-20T16:15:00Z&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;540&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;f&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;49&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;4dc9bbfbbc7a0515660052d3&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;Lois&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;55&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;f&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;0&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;4dc9bbfbbc7a0515660052c7&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;Horny&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;["carrot","papaya","orange"]&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;1992-03-14T07:47:00Z&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;600&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;m&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;63&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;4dc9bbfbbc7a0515660052c9&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;Unicrom&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;["energon","redbull","orange"]&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;1973-02-10T22:10:00Z&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;984&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;m&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;182&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;4dc9bbfbbc7a0515660052ca&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;Roooooodles&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;["apple","orange"]&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;1979-08-18T18:44:00Z&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;575&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;m&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;99&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;4dc9bbfbbc7a0515660052cd&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;Kenny&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;["grape","lemon","orange"]&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;1997-07-02T10:42:00Z&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;690&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;m&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;39&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;4dc9bbfbbc7a0515660052ce&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;Raleigh&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;["apple","sugar","orange"]&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;2005-05-04T00:57:00Z&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;421&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;m&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;2&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;4dc9bbfbbc7a0515660052d0&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;Pilot&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;["apple","watermelon","orange"]&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;1997-03-27T05:03:00Z&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;650&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;m&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;54&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;4dc9bbfbbc7a0515660052d2&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;Dunx&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;["grape","watermelon","orange"]&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;1976-07-19T19:18:00Z&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;704&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;m&lt;/div&gt;&lt;/td&gt;&lt;td style="border-bottom-color: rgb(240, 240, 240); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;div style="border-bottom-style: none; border-color: initial; border-left-style: none; border-right-style: none; border-top-style: none; border-width: initial; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-width: 300px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; padding-top: 4px; white-space: nowrap;"&gt;165&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-3723471778233460114?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/3723471778233460114/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=3723471778233460114' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/3723471778233460114'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/3723471778233460114'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2011/05/explore-mongodb.html' title='Explore MongoDB'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-1980955313833536442</id><published>2011-04-14T11:42:00.000-07:00</published><updated>2011-04-14T11:42:21.051-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DBA priority'/><title type='text'>What should the top five priorities be for new DBAs on the job?</title><content type='html'>&lt;span class="Apple-style-span" style="color: blue;"&gt;Thought it's helpful to read again and again.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #274e13;"&gt;&lt;b&gt;Be on fire.&lt;/b&gt; You have to want to learn everything, do everything, consume everything. So you got the DBA job, now is not the time to rest in your new chair and enjoy your success. List out your goals and what you want to learn. A five year plan is a great idea. &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #274e13;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #274e13;"&gt;&lt;b&gt;Listen! Ask Questions! Be involved! &lt;/b&gt;Don't just sit back waiting for the create table requests. &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #274e13;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #274e13;"&gt;When it comes to theory, &lt;b&gt;don't believe anything you hear or read until you have tried it yourself.&lt;/b&gt; Database rule number one, in my opinion, is that no rule of thumb applies all the time. &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #274e13;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #274e13;"&gt;If you are solely responsible for a database, make darned sure, before you leave your job on day one, that your &lt;b&gt;database can be recovered&lt;/b&gt;. Nothing else matters if you can't get that database back. &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #274e13;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #274e13;"&gt;&lt;b&gt;Document everything.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #274e13;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #274e13;"&gt;And, a baker's half-dozen... &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #274e13;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #274e13;"&gt;&lt;b&gt;Learn to use your voice of authority&lt;/b&gt;. You are the DBA, and this database is your responsibility. As you learn the right way, and the wrong way to do things (like, say, database design), you need to be an advocate for best practices and for good design. If you succeed, you can enjoy the rapture of success. If they don't listen, you will get the joy of "I told you so."&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #274e13;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #274e13;"&gt;&lt;a href="http://searchoracle.techtarget.com/news/1077095/So-you-want-to-be-a-DBA"&gt;http://searchoracle.techtarget.com/news/1077095/So-you-want-to-be-a-DBA&lt;/a&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-1980955313833536442?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/1980955313833536442/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=1980955313833536442' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/1980955313833536442'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/1980955313833536442'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2011/04/what-should-top-five-priorities-be-for.html' title='What should the top five priorities be for new DBAs on the job?'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-8880933124920480809</id><published>2010-10-29T11:39:00.001-07:00</published><updated>2011-06-07T16:45:50.281-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>effective index selectivity 2</title><content type='html'>File name...: A:\SQL\CBO\index_selectivity2.sql&lt;br /&gt;Usage.......: @file_name &lt;owner&gt; &lt;table_name&gt;&lt;br /&gt;Description.: Why we need to avoid implicit data conversions on index columns in predicate.&lt;br /&gt;Notes.......: index on VarChar2 columns&lt;br /&gt;Parameters..: &lt;br /&gt;Package.....: ._pkg&lt;br /&gt;&lt;br /&gt;Modification History:&lt;br /&gt;&lt;br /&gt;Date         Who          What&lt;br /&gt;29-Oct-2010: Charlie(Yi): Create the file,&lt;br /&gt;&lt;br /&gt;Goal&lt;br /&gt;----&lt;br /&gt;Show how implicit data conversions impact Effective Index Selectivity.&lt;br /&gt;Prove that developers rely on implicit conversions is a bad practice.&lt;br /&gt;&lt;br /&gt;Solution&lt;br /&gt;--------&lt;br /&gt;Create index on VarChar2 column(s), put number value in the predicate that use this index, &lt;br /&gt;cause implicitly data type conversion.&lt;br /&gt;E.g. TO_NUMBER(index_column) = n&lt;br /&gt;&lt;br /&gt;Spec&lt;br /&gt;----&lt;br /&gt;cost = blevel +&lt;br /&gt;ceiling(leaf_blocks * effective index selectivity) +&lt;br /&gt;ceiling(clustering_factor * effective table selectivity)&lt;br /&gt;&lt;br /&gt;Logical Reads(LIO) of index access = BLevel + leaf_blocks * effective index selectivity&lt;br /&gt;&lt;br /&gt;Buffers is LIO in function dbms_xplan.display_cursor output.&lt;br /&gt;&lt;br /&gt;See Page 62(91) of Book: [Cost-Based Oracle Fundamentals]&lt;br /&gt;&lt;br /&gt;Result&lt;br /&gt;------&lt;br /&gt;cost = 1 , LIO = 2 , No data conversion&lt;br /&gt;cost = 26, LIO = 28, data conversion, from char to number &lt;br /&gt;&lt;br /&gt;Data flow&lt;br /&gt;---------&lt;br /&gt;&lt;br /&gt;Test case&lt;br /&gt;---------&lt;br /&gt;* ,&lt;br /&gt;* ,&lt;br /&gt;&lt;br /&gt;Setup&lt;br /&gt;-----&lt;br /&gt;See below SQL code.&lt;br /&gt;&lt;br /&gt;Reference&lt;br /&gt;---&lt;br /&gt;QA..: You can send feedbacks or questions about this script to charlie.zhu1 gmail.com&lt;br /&gt;blog: http://mujiang.blogspot.com/&lt;br /&gt;&lt;br /&gt;&lt;/table_name&gt;&lt;/owner&gt;&lt;br /&gt;&lt;pre&gt;ALTER SESSION SET STATISTICS_LEVEL=TYPICAL;&lt;br /&gt;&lt;br /&gt;create table t&lt;br /&gt;(&lt;br /&gt;c1 VarChar2(5),&lt;br /&gt;c2 VarChar2(7)&lt;br /&gt;)&lt;br /&gt;nologging;&lt;br /&gt;&lt;br /&gt;create table t1&lt;br /&gt;(&lt;br /&gt;c1 varchar2(5),&lt;br /&gt;n1 number(5)&lt;br /&gt;)&lt;br /&gt;nologging;&lt;br /&gt;&lt;br /&gt;insert into t1(c1,n1) values('501',501);&lt;br /&gt;&lt;br /&gt;insert /*+ append */ into t(c1,c2)&lt;br /&gt;select mod(rownum,5), rownum&lt;br /&gt;from dual&lt;br /&gt;connect by level &amp;lt;=50000;&lt;br /&gt;&lt;br /&gt;commit;&lt;br /&gt;&lt;br /&gt;create unique index t_u1 on t(c1,c2) nologging;&lt;br /&gt;&lt;br /&gt;exec dbms_stats.gather_table_stats(user,'t');&lt;br /&gt;exec dbms_stats.gather_table_stats(user,'t1');&lt;br /&gt;&lt;br /&gt;set serveroutput off&lt;br /&gt;set linesize 200&lt;br /&gt;ALTER SESSION SET STATISTICS_LEVEL=ALL;&lt;br /&gt;&lt;br /&gt;REM -- use number value on VarChar2 index columns,&lt;br /&gt;&lt;br /&gt;select * from t&lt;br /&gt;where c1='1' and c2=(select n1 from t1);&lt;br /&gt;&lt;br /&gt;SELECT * FROM table(dbms_xplan.display_cursor(NULL,NULL, '+cost iostats memstats last partition'));&lt;br /&gt;&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;| Id  | Operation          | Name | Cost (%CPU)| Buffers |&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT   |      |    29 (100)|      35 |&lt;br /&gt;|*  1 |  INDEX RANGE SCAN  | T_U1 |    26   (0)|      35 |&lt;br /&gt;|   2 |   TABLE ACCESS FULL| T1   |     3   (0)|       7 |&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   1 - access("C1"='1')&lt;br /&gt;       filter(TO_NUMBER("C2")=)&lt;br /&gt;&lt;br /&gt;REM -- use string value on VarChar2 index columns,&lt;br /&gt;&lt;br /&gt;select * from t&lt;br /&gt;where c1='1' and c2=(select c1 from t1);&lt;br /&gt;&lt;br /&gt;SELECT * FROM table(dbms_xplan.display_cursor(NULL,NULL, 'cost iostats memstats last partition'));&lt;br /&gt;&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;| Id  | Operation          | Name | Cost (%CPU)| Buffers |&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT   |      |     4 (100)|       9 |&lt;br /&gt;|*  1 |  INDEX UNIQUE SCAN | T_U1 |     1   (0)|       9 |&lt;br /&gt;|   2 |   TABLE ACCESS FULL| T1   |     3   (0)|       7 |&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   1 - access("C1"='1' AND "C2"=)&lt;br /&gt;.&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-8880933124920480809?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/8880933124920480809/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=8880933124920480809' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/8880933124920480809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/8880933124920480809'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2010/10/effective-index-selectivity-2.html' title='effective index selectivity 2'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-1533917865724760533</id><published>2010-09-30T11:42:00.000-07:00</published><updated>2010-10-01T15:24:53.978-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dbms_rowid extent'/><title type='text'>Throttle big result set</title><content type='html'>&lt;h1&gt;Goal&lt;/h1&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;To process a big query result set from database, many a  time the application server is limited by memory footprint, so we need  to throttle the output chunk by chunk.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 32px; font-weight: bold;"&gt;Solution&lt;/span&gt;&lt;br /&gt;Q: How do you eat an elephant? A: One piece at a time.&lt;br /&gt;The  staging table will put into a tablespace with EXTENT MANAGEMENT LOCAL  UNIFORM SIZE 4M. you may choose other uniform size based on your result  size limit.&lt;br /&gt;And then we will read data one extent at a time, after finish one extent, mark it as processed.&lt;br /&gt;When client application crashed or failed, we can restart at failed extent.&lt;br /&gt;&lt;br /&gt;We may slow make the chunk across 2 or many extents to make it more flexible.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 32px; font-weight: bold;"&gt;Reference&lt;/span&gt;&lt;br /&gt;On the use of &lt;a class="tiddlyLink tiddlyLinkNonExisting" href="file:///A:/design/wiki/mj2010wiki.html" refresh="link" tiddlylink="DBMS_ROWID" title="The tiddler 'DBMS_ROWID' doesn't yet exist"&gt;DBMS_ROWID&lt;/a&gt;.rowid_create&lt;br /&gt;[&lt;a class="externalLink" href="http://bit.ly/bphHJb" target="_blank" title="External link to http://bit.ly/bphHJb"&gt;http://bit.ly/bphHJb&lt;/a&gt;]&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 32px; font-weight: bold;"&gt;Setup&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;drop table rowid_range_job purge;&lt;br /&gt;&lt;br /&gt;create table rowid_range_job&lt;br /&gt;tablespace data_auto nologging&lt;br /&gt;as&lt;br /&gt;select e.extent_id, e.block_id, e.block_id+blocks-1 block_id_end,&lt;br /&gt; cast(dbms_rowid.rowid_create( 1, o.data_object_id, e.file_id, e.block_id, 0 ) as urowid) min_rowid,&lt;br /&gt; cast(dbms_rowid.rowid_create( 1, o.data_object_id, e.file_id, e.block_id+e.blocks-1, 10000 ) as urowid) max_rowid,&lt;br /&gt; cast(o.object_name as varchar2(30)) table_name,&lt;br /&gt; cast(null as varchar2(30)) partition_name,&lt;br /&gt; cast('isbn_extract' as varchar2(30)) job_name,&lt;br /&gt; cast(null as date)         process_date,&lt;br /&gt; cast(null as number(1))    is_processed&lt;br /&gt;from dba_extents e, user_objects o&lt;br /&gt; where o.object_name = 'T'&lt;br /&gt;   and e.segment_name = 'T'&lt;br /&gt;   and e.owner = user&lt;br /&gt;   and e.segment_type = 'TABLE'&lt;br /&gt; order by e.extent_id&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;drop table t purge;&lt;br /&gt;create table t&lt;br /&gt;(&lt;br /&gt;n1 number(10),&lt;br /&gt;d1 date,&lt;br /&gt;c1 varchar2(2000)&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;insert --+ append&lt;br /&gt; into t(n1,d1,c1)&lt;br /&gt;select rownum, sysdate, rpad('a',1200)&lt;br /&gt;from dual&lt;br /&gt;connect by level &amp;lt;= 10000;&lt;br /&gt;commit;&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;br /&gt;Generate and check rowid range split,&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="white-space: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;pre&gt;with data as&lt;br /&gt;(&lt;br /&gt;select e.extent_id, e.block_id, e.block_id+blocks-1,&lt;br /&gt;       dbms_rowid.rowid_create( 1, o.data_object_id, e.file_id, e.block_id, 0 ) min_rowid,&lt;br /&gt;       dbms_rowid.rowid_create( 1, o.data_object_id, e.file_id, e.block_id+e.blocks-1, 10000 ) max_rowid&lt;br /&gt;  from dba_extents e,&lt;br /&gt;       user_objects o&lt;br /&gt; where o.object_name = 'T'&lt;br /&gt;   and e.segment_name = o.object_name&lt;br /&gt;   and e.owner = user&lt;br /&gt;   and e.segment_type = 'TABLE'&lt;br /&gt;)&lt;br /&gt;select extent_id, count(*) cnt&lt;br /&gt;  from data, T t&lt;br /&gt; where t.rowid between data.min_rowid and data.max_rowid&lt;br /&gt; group by rollup (extent_id)&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;delete rowid_range_job where job_name = 'test_output_job';&lt;br /&gt;&lt;br /&gt;INSERT INTO rowid_range_job&lt;br /&gt;   SELECT   e.extent_id, e.block_id, e.block_id + blocks - 1 block_id_end,&lt;br /&gt;            CAST&lt;br /&gt;               (DBMS_ROWID.rowid_create (1,&lt;br /&gt;                                         o.data_object_id,&lt;br /&gt;                                         e.file_id,&lt;br /&gt;                                         e.block_id,&lt;br /&gt;                                         0&lt;br /&gt;                                        ) AS UROWID&lt;br /&gt;               ) min_rowid,&lt;br /&gt;            CAST&lt;br /&gt;               (DBMS_ROWID.rowid_create (1,&lt;br /&gt;                                         o.data_object_id,&lt;br /&gt;                                         e.file_id,&lt;br /&gt;                                         e.block_id + e.blocks - 1,&lt;br /&gt;                                         32000&lt;br /&gt;                                        ) AS UROWID&lt;br /&gt;               ) max_rowid,&lt;br /&gt;            CAST (o.object_name AS VARCHAR2 (30)) table_name,&lt;br /&gt;            CAST (NULL AS VARCHAR2 (30)) partition_name,&lt;br /&gt;            CAST ('test_output_job' AS VARCHAR2 (30)) job_name,&lt;br /&gt;            CAST (NULL AS DATE) process_date, 0 is_processed&lt;br /&gt;       FROM dba_extents e, user_objects o&lt;br /&gt;      WHERE o.object_name LIKE 'T'&lt;br /&gt;        AND e.segment_name = o.object_name&lt;br /&gt;        AND e.owner = USER&lt;br /&gt;        AND e.segment_type = 'TABLE'&lt;br /&gt;   ORDER BY o.object_name, e.extent_id;&lt;br /&gt;&lt;br /&gt;commit;&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;br /&gt;Query rowid extent range split metadata&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="white-space: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;pre&gt;select EXTENT_ID,&lt;br /&gt;BLOCK_ID,&lt;br /&gt;BLOCK_ID_END,&lt;br /&gt;MIN_ROWID,&lt;br /&gt;MAX_ROWID&lt;br /&gt;--,TABLE_NAME&lt;br /&gt;--,PARTITION_NAME&lt;br /&gt;--,JOB_NAME&lt;br /&gt;--,PROCESS_DATE&lt;br /&gt;--,IS_PROCESSED &lt;br /&gt;from invdb.rowid_range_job where job_name = 'test_output_job';&lt;br /&gt;&lt;br /&gt;with data as&lt;br /&gt;(&lt;br /&gt;  select extent_id, block_id, block_id_end, min_rowid, max_rowid, table_name, job_name, process_date, is_processed&lt;br /&gt;  from rowid_range_job&lt;br /&gt;  where job_name = 'test_output_job'&lt;br /&gt;    and table_name = 'T'&lt;br /&gt;)&lt;br /&gt;select extent_id, count(*) cnt&lt;br /&gt;  from data, T t&lt;br /&gt; where t.rowid between data.min_rowid and data.max_rowid&lt;br /&gt; group by rollup (extent_id)&lt;br /&gt;/&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-1533917865724760533?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/1533917865724760533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=1533917865724760533' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/1533917865724760533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/1533917865724760533'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2010/09/throttle-big-result-set.html' title='Throttle big result set'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-5128919647142480600</id><published>2010-08-16T14:05:00.000-07:00</published><updated>2011-11-07T15:07:08.988-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>IN_EXISTS Correlated Subquery</title><content type='html'>&lt;div class="viewer"&gt;&lt;h1&gt;Goal&lt;/h1&gt;To show how IN and EXISTS Correlated Subquery works, and how they changed in Oracle 11g CBO SQL Engine. Also covered the NOT IN and NOT EXISTS difference.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Setup&lt;/h1&gt;&lt;pre&gt;drop table t1 cascade constraints purge;&lt;br /&gt;drop table t2 purge;&lt;br /&gt;&lt;br /&gt;create table t1(x number);&lt;br /&gt;create table t2(y number);&lt;br /&gt;&lt;br /&gt;insert into t1(x) values(1);&lt;br /&gt;insert into t1(x) values(2);&lt;br /&gt;insert into t1(x) values(Null);&lt;br /&gt;&lt;br /&gt;insert into t2(y) values(1);&lt;br /&gt;insert into t2(y) values(Null);&lt;br /&gt;commit;&lt;br /&gt;&lt;br /&gt;create index t1_x on t1(x);&lt;br /&gt;create index t2_y on t2(y);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h1&gt;IN&lt;/h1&gt;t2 is small, index on t1.x, the subquery ( select y from T2 ) is small, probable &lt;strong&gt;full scan t2&lt;/strong&gt;&lt;br /&gt;&lt;pre&gt;Select * from T1 where x in&lt;br /&gt; ( select y from T2 );&lt;br /&gt;=&lt;br /&gt;select * &lt;br /&gt;  from t1, ( select distinct y from t2 ) t2&lt;br /&gt; where t1.x = t2.y;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Small t2,&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;set autot trace exp&lt;br /&gt;&lt;br /&gt;Select /*+ cardinality(t1,50000) */ * from T1 where x in&lt;br /&gt; ( select /*+ cardinality(t2, 200) */ y from T2 );&lt;br /&gt;------------------------------------------&lt;br /&gt;| Id  | Operation         | Name | Rows  |&lt;br /&gt;------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT  |      |   224 |&lt;br /&gt;|   1 |  NESTED LOOPS     |      |   224 |&lt;br /&gt;|   2 |   SORT UNIQUE     |      |   200 |&lt;br /&gt;|   3 |    INDEX FULL SCAN| T2_Y |   200 |&lt;br /&gt;|*  4 |   INDEX RANGE SCAN| T1_X |     1 |&lt;br /&gt;------------------------------------------&lt;br /&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;Small t1&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;Select /*+ cardinality(t1,500) */ * from T1 where x in&lt;br /&gt; ( select /*+ cardinality(t2, 20000) */ y from T2 );&lt;br /&gt;------------------------------------------&lt;br /&gt;| Id  | Operation         | Name | Rows  |&lt;br /&gt;------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT  |      |   500 |&lt;br /&gt;|   1 |  NESTED LOOPS SEMI|      |   500 |&lt;br /&gt;|   2 |   INDEX FULL SCAN | T1_X |   500 |&lt;br /&gt;|*  3 |   INDEX RANGE SCAN| T2_Y | 20000 |&lt;br /&gt;------------------------------------------&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h1&gt;Exists&lt;/h1&gt;t1 is small, index on t2(y), &lt;strong&gt;full scan t1&lt;/strong&gt;,&lt;br /&gt;&lt;pre&gt;select * from t1 &lt;br /&gt; where exists ( select null from t2 where y = x );&lt;br /&gt;=&lt;br /&gt;   for x in ( select * from t1 )&lt;br /&gt;   loop&lt;br /&gt;      if ( exists ( select null from t2 where y = x.x )&lt;br /&gt;      then &lt;br /&gt;         OUTPUT THE RECORD&lt;br /&gt;      end if&lt;br /&gt;   end loop&lt;br /&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;Small t2,&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;select /*+ cardinality(t1,50000) */ * from t1 &lt;br /&gt; where exists ( select /*+ cardinality(t2, 700) */ null from t2 where y = x );&lt;br /&gt;------------------------------------------&lt;br /&gt;| Id  | Operation         | Name | Rows  |&lt;br /&gt;------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT  |      |   782 |&lt;br /&gt;|   1 |  NESTED LOOPS     |      |   782 |&lt;br /&gt;|   2 |   SORT UNIQUE     |      |   700 |&lt;br /&gt;|   3 |    INDEX FULL SCAN| T2_Y |   700 |&lt;br /&gt;|*  4 |   INDEX RANGE SCAN| T1_X |     1 |&lt;br /&gt;------------------------------------------&lt;br /&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;Small t1&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;select /*+ cardinality(t1,500) */ * from t1 &lt;br /&gt; where exists ( select /*+ cardinality(t2, 70000) */ null from t2 where y = x );&lt;br /&gt;------------------------------------------&lt;br /&gt;| Id  | Operation         | Name | Rows  |&lt;br /&gt;------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT  |      |   500 |&lt;br /&gt;|   1 |  NESTED LOOPS SEMI|      |   500 |&lt;br /&gt;|   2 |   INDEX FULL SCAN | T1_X |   500 |&lt;br /&gt;|*  3 |   INDEX RANGE SCAN| T2_Y | 70000 |&lt;br /&gt;------------------------------------------&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If both the subquery and the outer table are huge — either might work as well as the &lt;br /&gt;other — depends on the indexes and other factors.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt; Not in and Not exists are different.&lt;/h3&gt;&lt;pre&gt;select * from t1 outer&lt;br /&gt;where outer.x not in (select y from t2);&lt;br /&gt;&lt;/pre&gt;is NOT the same as&lt;br /&gt;&lt;pre&gt;select * from t1 outer&lt;br /&gt;where not exists (select null from t2 where t2.y = outer.x);&lt;br /&gt;&lt;/pre&gt;UNLESS the expression "y" is not null. That said:&lt;br /&gt;&lt;pre&gt;select * from t1 outer&lt;br /&gt;where outer.x not in (select y from t2 where y is not null);&lt;br /&gt;&lt;/pre&gt;is the same as&lt;br /&gt;&lt;pre&gt;select * from t1 outer&lt;br /&gt;where not exists (select null from t2 where t2.y = outer.x);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt; If t.y is null-able,&lt;/h4&gt;&lt;pre&gt;select * from t1 outer&lt;br /&gt;where outer.x not in (select y from t2 where y is null);&lt;br /&gt;&lt;br /&gt;select * from t1 outer&lt;br /&gt;where outer.x not in (2,3,Null);&lt;br /&gt;&lt;/pre&gt;return no rows.&lt;br /&gt;&lt;br /&gt;select * from t1 outer&lt;br /&gt;where outer.x not in (2,3);&lt;br /&gt;&lt;br /&gt;IN &amp;amp; EXISTS, &lt;a class="tiddlyLink tiddlyLinkNonExisting" href="file:///A:/design/wiki/mj2010wiki.html" refresh="link" tiddlylink="AskTom" title="The tiddler 'AskTom' doesn't yet exist"&gt;AskTom&lt;/a&gt;, &lt;a class="externalLink" href="http://bit.ly/aLvOeS" target="_blank" title="External link to http://bit.ly/aLvOeS"&gt;http://bit.ly/aLvOeS&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;h2&gt; Set Stats&lt;/h2&gt;&lt;pre&gt;declare&lt;br /&gt; m_distcnt  number;&lt;br /&gt; m_density  number;&lt;br /&gt; m_nullcnt  number;&lt;br /&gt; m_avgclen  number;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt; m_distcnt := 200100;&lt;br /&gt; m_density := 0.002;&lt;br /&gt; m_nullcnt := 0;&lt;br /&gt; m_avgclen := 5;&lt;br /&gt;&lt;br /&gt; dbms_stats.set_column_stats(&lt;br /&gt;  ownname  =&amp;gt; user,&lt;br /&gt;  tabname  =&amp;gt; 't1',&lt;br /&gt;  colname  =&amp;gt; 'x',&lt;br /&gt;  distcnt  =&amp;gt; m_distcnt,&lt;br /&gt;  density  =&amp;gt; m_density,&lt;br /&gt;  nullcnt  =&amp;gt; m_nullcnt,&lt;br /&gt;  avgclen  =&amp;gt; m_avgclen&lt;br /&gt; );&lt;br /&gt;&lt;br /&gt; dbms_stats.set_column_stats(&lt;br /&gt;  ownname  =&amp;gt; user,&lt;br /&gt;  tabname  =&amp;gt; 't2',&lt;br /&gt;  colname  =&amp;gt; 'y',&lt;br /&gt;  distcnt  =&amp;gt; m_distcnt,&lt;br /&gt;  density  =&amp;gt; m_density,&lt;br /&gt;  nullcnt  =&amp;gt; m_nullcnt,&lt;br /&gt;  avgclen  =&amp;gt; m_avgclen&lt;br /&gt; );&lt;br /&gt;&lt;br /&gt;  dbms_stats.set_table_stats( user, 't1', numrows =&amp;gt; 2000000, numblks =&amp;gt; 1000000);&lt;br /&gt;  dbms_stats.set_table_stats( user, 't2', numrows =&amp;gt; 2000000, numblks =&amp;gt; 1000000);&lt;br /&gt;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;select  table_name,&lt;br /&gt; num_rows,&lt;br /&gt; blocks&lt;br /&gt;from&lt;br /&gt; user_tables&lt;br /&gt;where&lt;br /&gt; table_name in ('T1','T2')&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;select&lt;br /&gt; num_distinct,&lt;br /&gt; low_value,&lt;br /&gt; high_value,&lt;br /&gt; density,&lt;br /&gt; num_nulls,&lt;br /&gt; num_buckets,&lt;br /&gt; histogram&lt;br /&gt;from&lt;br /&gt; user_tab_columns&lt;br /&gt;where&lt;br /&gt; table_name in ('T1','T2')&lt;br /&gt;and column_name in ('X','Y')&lt;br /&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-5128919647142480600?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/5128919647142480600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=5128919647142480600' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/5128919647142480600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/5128919647142480600'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2010/08/inexists-correlated-subquery.html' title='IN_EXISTS Correlated Subquery'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-8690050468629424738</id><published>2010-05-18T11:09:00.000-07:00</published><updated>2010-05-18T11:10:20.047-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='collection'/><category scheme='http://www.blogger.com/atom/ns#' term='array'/><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>Collection_Array</title><content type='html'>PL/SQL has three collection types, Tom often demos with Nested Table and Associative Array.&lt;br /&gt;Associative Array is most flexible on element indexing. Nested Table is good enough for Bulk Fetching.&lt;br /&gt;&lt;br /&gt;But Bryn Llewellyn, Oracle PL/SQL Product Manager likes to use &lt;a class="tiddlyLink tiddlyLinkNonExisting" href="file:///A:/design/wiki/mj2010wiki.html" refresh="link" tiddlylink="VArray" title="The tiddler 'VArray' doesn't yet exist"&gt;VArray&lt;/a&gt; in his demo.&lt;br /&gt;"the collection is best declared as a varray with a maximum size equal to Batchsize."&lt;br /&gt;See &lt;a class="externalLink" href="http://www.oracle.com/technology/tech/pl_sql/pdf/doing_sql_from_plsql.pdf" target="_blank" title="External link to http://www.oracle.com/technology/tech/pl_sql/pdf/doing_sql_from_plsql.pdf"&gt;http://www.oracle.com/technology/tech/pl_sql/pdf/doing_sql_from_plsql.pdf&lt;/a&gt;&lt;br /&gt;Probably he knows that VARRAY implemented with the most efficient internal storage, and delivery the best performance, when correctly used; it may meet most of the requirements for loop batch bulk fetching.&lt;br /&gt;To find out the details, you may do a simple &lt;a class="externalLink" href="http://mujiang.blogspot.com/2010/05/benchmark-with-runstats.html" target="_blank" title="External link to http://mujiang.blogspot.com/2010/05/benchmark-with-runstats.html"&gt;RunStats&lt;/a&gt; benchmark.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Associative Array type(or index-by table)&lt;/li&gt;&lt;/ul&gt;&lt;code&gt;TYPE population IS TABLE OF NUMBER INDEX BY VARCHAR2(64);&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Nested Tables&lt;/li&gt;&lt;/ul&gt;&lt;code&gt;TYPE nested_type IS TABLE OF VARCHAR2(30);&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;ul&gt;&lt;li&gt;invoke EXTEND method to add elements later&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Collection of ADT = UDT, Abstract datatype, User defined datatype:&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;CREATE OR REPLACE TYPE INVDB.NUMBER_TAB_TYPE is table of number;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;select ... from TABLE(ADT_Table_Instance);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;blockquote&gt;Comments, Bulk fetch into ADT is not efficient, you may see the workaround in paper doing_sql_from_plsql.pdf&lt;/blockquote&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Variable-size array (varray)&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;-- Code_30 Many_Row_Select.sql&lt;br /&gt;Batchsize constant pls_integer := 1000;&lt;br /&gt;&lt;br /&gt;type Result_t is record(PK t.PK%type, v1 t.v1%type);&lt;br /&gt;type Results_t is varray(1000) of Result_t;&lt;br /&gt;Results Results_t;&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;Concept&lt;/h3&gt;&lt;ul&gt;&lt;li&gt; Associative Array: sparse array.&lt;/li&gt;&lt;li&gt; Nested Table or ADT/UDT : dense array&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;REM Associative Array&lt;br /&gt;declare&lt;br /&gt;   type date_aat is table of date index by binary_integer;&lt;br /&gt;   l_data date_aat;&lt;br /&gt;begin&lt;br /&gt;   l_data(-200) := sysdate;&lt;br /&gt;   l_data(+200) := sysdate+1;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;collection(elements), e.g. &lt;code&gt;collection_instance(element_unique_subscript_index_number)&lt;/code&gt;&lt;br /&gt;record_name.field_name&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-8690050468629424738?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/8690050468629424738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=8690050468629424738' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/8690050468629424738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/8690050468629424738'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2010/05/collectionarray.html' title='Collection_Array'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-2394250855386621351</id><published>2010-05-03T11:48:00.000-07:00</published><updated>2011-02-01T13:22:32.959-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><category scheme='http://www.blogger.com/atom/ns#' term='benchmark'/><title type='text'>Benchmark with RunStats</title><content type='html'>There are many approaches and tools to benchmark Oracle application.&lt;br /&gt;E.g.&lt;br /&gt;* mystat.sql and mystat2.sql&lt;br /&gt;* SQL session trace and tkprof&lt;br /&gt;* SET AUTOT[RACE] {OFF | ON | TRACE[ONLY]} [EXP[LAIN]] [STAT[ISTICS]]&lt;br /&gt;* ASH/AWR&lt;br /&gt;* SQL hint /*+ gather_plan_statistics */ and dbms_xplan.display_cursor(NULL,NULL, 'iostats memstats last partition');&lt;br /&gt;* ALTER SESSION SET STATISTICS_LEVEL=ALL;&lt;br /&gt;* Real-Time SQL Monitoring&lt;br /&gt;&lt;br /&gt;My favorite one is Tom's RunStats. Here is the one I enhanced from Tom's original version.&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;Goal&lt;br /&gt;----&lt;br /&gt;Persistent the benchmark stats, and then developer can query the report later.&lt;br /&gt;&lt;br /&gt;Solution&lt;br /&gt;--------&lt;br /&gt;Add an IP column to utility.run_stats_save table, get computer IP by SYS_CONTEXT function.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Reference&lt;br /&gt;---------&lt;br /&gt;file://a:/Tuning/Trace/RunStatsSave.sql&lt;br /&gt;&lt;br /&gt;http://tkyte.blogspot.com/2009/10/httpasktomoraclecomtkyte.html&lt;br /&gt;&lt;br /&gt;How to build a simple test harness (RUNSTATS) (HOWTO) to test two different approaches from a performance perspective.&lt;br /&gt;&lt;br /&gt;Runstats.sql&lt;br /&gt;This is the test harness I use to try out different ideas. It shows two vital sets of statistics for me &lt;br /&gt;The elapsed time difference between two approaches. It very simply shows me which approach is faster by the wall clock &lt;br /&gt;How many resources each approach takes. This can be more meaningful then even the wall clock timings. For example, if one approach is faster then the other but it takes thousands of latches (locks), I might avoid it simply because it will not scale as well. &lt;br /&gt;The way this test harness works is by saving the system statistics and latch information into a temporary table. We then run a test and take another snapshot. We run the second test and take yet another snapshot. Now we can show the amount of resources used by approach 1 and approach 2. &lt;br /&gt;Requirements &lt;br /&gt;&lt;br /&gt;In order to run this test harness you must at a minimum have: &lt;br /&gt;&lt;br /&gt;Access to V$STATNAME, V$MYSTAT, v$TIMER and V$LATCH &lt;br /&gt;You must be granted select DIRECTLY on SYS.V_$STATNAME, SYS.V_$MYSTAT, SYS.V_$TIMER and SYS.V_$LATCH. It will not work to have select on these via a ROLE. &lt;br /&gt;The ability to create a table -- run_stats -- to hold the before, during and after information. &lt;br /&gt;The ability to create a package -- rs_pkg -- the statistics collection/reporting piece &lt;br /&gt;You should note also that the LATCH information is collected on a SYSTEM WIDE basis. If you run this on a multi-user system, the latch information may be technically "incorrect" as you will count the latching information for other sessions - not just your session. This test harness works best in a simple, controlled test environment. &lt;br /&gt;&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;CREATE USER utility&lt;br /&gt;  IDENTIFIED BY ?&lt;br /&gt;  DEFAULT TABLESPACE USERS quota unlimited on users&lt;br /&gt;ACCOUNT UNLOCK;&lt;br /&gt;&lt;br /&gt;grant unlimited tablespace to utility;&lt;br /&gt;&lt;br /&gt;create role schema_admin;&lt;br /&gt;&lt;br /&gt;grant create session, create table, create view, &lt;br /&gt; create procedure, create trigger, create any directory,&lt;br /&gt; CREATE SEQUENCE, CREATE TYPE, CREATE SYNONYM,&lt;br /&gt; create materialized view, create dimension,&lt;br /&gt; SELECT_CATALOG_ROLE,&lt;br /&gt; create database link,create public database link, drop public database link,&lt;br /&gt; create job&lt;br /&gt;to schema_admin;&lt;br /&gt;&lt;br /&gt;grant schema_admin to utility;&lt;br /&gt;-- grant create procedure, create table to utility;&lt;br /&gt;&lt;br /&gt;grant select on SYS.V_$STATNAME to utility;&lt;br /&gt;grant select on SYS.V_$MYSTAT to utility;&lt;br /&gt;grant select on SYS.V_$TIMER to utility;&lt;br /&gt;grant select on SYS.V_$LATCH to utility;&lt;br /&gt;&lt;br /&gt;drop table utility.run_stats;&lt;br /&gt;drop table utility.run_stats_save;&lt;br /&gt;&lt;br /&gt;create global temporary table utility.run_stats&lt;br /&gt;( runid varchar2(15),&lt;br /&gt;  name varchar2(80),&lt;br /&gt;  value int )&lt;br /&gt;on commit preserve rows;&lt;br /&gt;&lt;br /&gt;-- Store the stats for later reporting&lt;br /&gt;create table utility.run_stats_save&lt;br /&gt;( &lt;br /&gt;runid varchar2(15),&lt;br /&gt;name varchar2(80),&lt;br /&gt;value int,&lt;br /&gt;IP varchar2(30),&lt;br /&gt;hostname varchar2(30)&lt;br /&gt;) tablespace users;&lt;br /&gt;&lt;br /&gt;create or replace view utility.stats&lt;br /&gt;as select 'STAT...' || a.name name, b.value&lt;br /&gt;      from v$statname a, v$mystat b&lt;br /&gt;     where a.statistic# = b.statistic#&lt;br /&gt;    union all&lt;br /&gt;    select 'LATCH.' || name,  gets&lt;br /&gt;      from v$latch&lt;br /&gt; union all&lt;br /&gt; select 'STAT...Elapsed Time', hsecs from v$timer;&lt;br /&gt;/*&lt;br /&gt;SYS_CONTEXT&lt;br /&gt;&lt;br /&gt;The SYS_CONTEXT function is able to return the following host and IP address information for the current session:&lt;br /&gt;&lt;br /&gt;TERMINAL - An operating system identifier for the current session. This is often the client machine name. &lt;br /&gt;HOST - The host name of the client machine. &lt;br /&gt;IP_ADDRESS - The IP address of the client machine. &lt;br /&gt;SERVER_HOST - The host name of the server running the database instance. &lt;br /&gt;&lt;br /&gt;SELECT SYS_CONTEXT('USERENV','HOST') FROM dual;&lt;br /&gt;----------&lt;br /&gt;GATES2\SKY&lt;br /&gt;&lt;br /&gt;SELECT terminal, machine FROM v$session &lt;br /&gt;where sid = (select sid from v$mystat where rownum &amp;lt;= 1);&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;CREATE OR REPLACE package utility.runstats_pkg&lt;br /&gt;as&lt;br /&gt;  TYPE print_tab     IS TABLE OF varchar2(200);&lt;br /&gt;  --l_print dbms_sql.VARCHAR2_TABLE; &lt;br /&gt;    procedure rs_start;&lt;br /&gt;    procedure rs_middle;&lt;br /&gt;    procedure rs_stop( p_difference_threshold in number default 0 );&lt;br /&gt;    procedure rs_report( p_difference_threshold in number default 0, p_host in varchar2 default Null );&lt;br /&gt;  function rs_report( p_difference_threshold in number default 0, p_host in varchar2 default Null )&lt;br /&gt;  return print_tab PIPELINED DETERMINISTIC;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;CREATE OR REPLACE package body utility.runstats_pkg&lt;br /&gt;as&lt;br /&gt;&lt;br /&gt;g_start number;&lt;br /&gt;g_run1  number;&lt;br /&gt;g_run2  number;&lt;br /&gt;g_host varchar2(30);&lt;br /&gt;g_ip varchar2(30);&lt;br /&gt;&lt;br /&gt;procedure rs_start&lt;br /&gt;is&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt;  g_host := substr(SYS_CONTEXT('USERENV','TERMINAL'),1,30);&lt;br /&gt;  g_ip := substr(SYS_CONTEXT('USERENV','IP_ADDRESS'),1,30);&lt;br /&gt;  delete from run_stats_save where hostname = g_host;&lt;br /&gt;&lt;br /&gt;    execute immediate 'truncate table run_stats';&lt;br /&gt;    delete from run_stats;&lt;br /&gt;&lt;br /&gt;    insert into run_stats&lt;br /&gt;    select 'before', stats.* from stats;&lt;br /&gt;&lt;br /&gt;    g_start := dbms_utility.get_time;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure rs_middle&lt;br /&gt;is&lt;br /&gt;begin&lt;br /&gt;    g_run1 := (dbms_utility.get_time-g_start);&lt;br /&gt;&lt;br /&gt;    insert into run_stats&lt;br /&gt;    select 'after 1', stats.* from stats;&lt;br /&gt;    g_start := dbms_utility.get_time;&lt;br /&gt;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure rs_stop(p_difference_threshold in number default 0)&lt;br /&gt;is&lt;br /&gt;begin&lt;br /&gt;    g_run2 := (dbms_utility.get_time-g_start);&lt;br /&gt;&lt;br /&gt;    dbms_output.put_line&lt;br /&gt;    ( 'Run1 ran in ' || g_run1 || ' hsecs' );&lt;br /&gt;    dbms_output.put_line&lt;br /&gt;    ( 'Run2 ran in ' || g_run2 || ' hsecs' );&lt;br /&gt;    dbms_output.put_line&lt;br /&gt;    ( 'run 1 ran in ' || round(g_run1/g_run2*100,2) ||&lt;br /&gt;      '% of the time' );&lt;br /&gt;    dbms_output.put_line( chr(9) );&lt;br /&gt;&lt;br /&gt;    insert into run_stats&lt;br /&gt;    select 'after 2', stats.* from stats;&lt;br /&gt;&lt;br /&gt;    insert into run_stats_save (RUNID,NAME,VALUE,IP,HOSTNAME)&lt;br /&gt;    select RUNID,NAME,VALUE, g_ip, g_host from run_stats;&lt;br /&gt;&lt;br /&gt;    commit;&lt;br /&gt;&lt;br /&gt;    dbms_output.put_line&lt;br /&gt;    ( rpad( 'Name', 40 ) || lpad( 'Run1', 14 ) ||&lt;br /&gt;      lpad( 'Run2', 14 ) || lpad( 'Diff', 14 ) );&lt;br /&gt;&lt;br /&gt;    for x in&lt;br /&gt;    ( select rpad( a.name, 40 ) ||&lt;br /&gt;             to_char( b.value-a.value, '99999,999,999' ) ||&lt;br /&gt;             to_char( c.value-b.value, '99999,999,999' ) ||&lt;br /&gt;             to_char( ( (c.value-b.value)-(b.value-a.value)), '99999,999,999' ) data&lt;br /&gt;        from run_stats a, run_stats b, run_stats c&lt;br /&gt;       where a.name = b.name&lt;br /&gt;         and b.name = c.name&lt;br /&gt;         and a.runid = 'before'&lt;br /&gt;         and b.runid = 'after 1'&lt;br /&gt;         and c.runid = 'after 2'&lt;br /&gt;         -- and (c.value-a.value) &amp;gt; 0&lt;br /&gt;         and abs( (c.value-b.value) - (b.value-a.value) )&lt;br /&gt;               &amp;gt; p_difference_threshold&lt;br /&gt;       order by abs( (c.value-b.value)-(b.value-a.value)), data&lt;br /&gt;    ) loop&lt;br /&gt;        dbms_output.put_line( x.data );&lt;br /&gt;    end loop;&lt;br /&gt;&lt;br /&gt;    dbms_output.put_line( chr(9) );&lt;br /&gt;    dbms_output.put_line&lt;br /&gt;    ( 'Run1 latches total versus run2 -- difference and pct' );&lt;br /&gt;    dbms_output.put_line&lt;br /&gt;    ('.'|| lpad( 'Run1', 14 ) || lpad( 'Run2', 14 ) ||&lt;br /&gt;      lpad( 'Diff', 14 ) || lpad( 'Pct', 11 ) );&lt;br /&gt;&lt;br /&gt;    for x in&lt;br /&gt;    ( select '.'||&lt;br /&gt;             to_char( run1, '99999,999,999' ) ||&lt;br /&gt;             to_char( run2, '99999,999,999' ) ||&lt;br /&gt;             to_char( diff, '99999,999,999' ) ||&lt;br /&gt;             to_char( round( run1/run2*100,2 ), '99,999.99' ) || '%' data&lt;br /&gt;        from ( select sum(b.value-a.value) run1, sum(c.value-b.value) run2,&lt;br /&gt;                      sum( (c.value-b.value)-(b.value-a.value)) diff&lt;br /&gt;                 from run_stats a, run_stats b, run_stats c&lt;br /&gt;                where a.name = b.name&lt;br /&gt;                  and b.name = c.name&lt;br /&gt;                  and a.runid = 'before'&lt;br /&gt;                  and b.runid = 'after 1'&lt;br /&gt;                  and c.runid = 'after 2'&lt;br /&gt;                  and a.name like 'LATCH%'&lt;br /&gt;                )&lt;br /&gt;    ) loop&lt;br /&gt;        dbms_output.put_line( x.data );&lt;br /&gt;    end loop;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure rs_report( p_difference_threshold in number default 0, p_host in varchar2 default Null )&lt;br /&gt;is&lt;br /&gt;begin&lt;br /&gt;  g_host := substr(SYS_CONTEXT('USERENV','TERMINAL'),1,30);&lt;br /&gt;  g_ip := substr(SYS_CONTEXT('USERENV','IP_ADDRESS'),1,30);&lt;br /&gt;&lt;br /&gt;    g_run2 := (dbms_utility.get_time-g_start);&lt;br /&gt;&lt;br /&gt;    dbms_output.put_line&lt;br /&gt;    ( 'Run1 ran in ' || g_run1 || ' hsecs' );&lt;br /&gt;    dbms_output.put_line&lt;br /&gt;    ( 'Run2 ran in ' || g_run2 || ' hsecs' );&lt;br /&gt;    dbms_output.put_line&lt;br /&gt;    ( 'run 1 ran in ' || round(g_run1/g_run2*100,2) ||&lt;br /&gt;      '% of the time' );&lt;br /&gt;    dbms_output.put_line( chr(9) );&lt;br /&gt;&lt;br /&gt;    dbms_output.put_line&lt;br /&gt;    ( rpad( 'Name', 40 ) || lpad( 'Run1', 14 ) ||&lt;br /&gt;      lpad( 'Run2', 14 ) || lpad( 'Diff', 14 ) );&lt;br /&gt;&lt;br /&gt;    for x in&lt;br /&gt;    ( select rpad( a.name, 40 ) ||&lt;br /&gt;             to_char( b.value-a.value, '99999,999,999' ) ||&lt;br /&gt;             to_char( c.value-b.value, '99999,999,999' ) ||&lt;br /&gt;             to_char( ( (c.value-b.value)-(b.value-a.value)), '99999,999,999' ) data&lt;br /&gt;        from run_stats_save a, run_stats_save b, run_stats_save c&lt;br /&gt;       where a.name = b.name&lt;br /&gt;         and b.name = c.name&lt;br /&gt;         and a.runid = 'before'&lt;br /&gt;         and b.runid = 'after 1'&lt;br /&gt;         and c.runid = 'after 2'&lt;br /&gt;         -- and (c.value-a.value) &amp;gt; 0&lt;br /&gt;         and abs( (c.value-b.value) - (b.value-a.value) )&lt;br /&gt;               &amp;gt; p_difference_threshold&lt;br /&gt;         and a.hostname = g_host&lt;br /&gt;         and a.hostname = b.hostname&lt;br /&gt;         and a.hostname = c.hostname&lt;br /&gt;       order by abs( (c.value-b.value)-(b.value-a.value))&lt;br /&gt;    ) loop&lt;br /&gt;        dbms_output.put_line( x.data );&lt;br /&gt;    end loop;&lt;br /&gt;&lt;br /&gt;    dbms_output.put_line( chr(9) );&lt;br /&gt;    dbms_output.put_line&lt;br /&gt;    ( 'Run1 latches total versus run2 -- difference and pct' );&lt;br /&gt;    dbms_output.put_line&lt;br /&gt;    ( lpad( 'Run1', 14 ) || lpad( 'Run2', 14 ) ||&lt;br /&gt;      lpad( 'Diff', 14 ) || lpad( 'Pct', 11 ) );&lt;br /&gt;&lt;br /&gt;    for x in&lt;br /&gt;    ( select to_char( run1, '99999,999,999' ) ||&lt;br /&gt;             to_char( run2, '99999,999,999' ) ||&lt;br /&gt;             to_char( diff, '99999,999,999' ) ||&lt;br /&gt;             to_char( round( run1/run2*100,2 ), '99,999.99' ) || '%' data&lt;br /&gt;        from ( select sum(b.value-a.value) run1, sum(c.value-b.value) run2,&lt;br /&gt;                      sum( (c.value-b.value)-(b.value-a.value)) diff&lt;br /&gt;                 from run_stats_save a, run_stats_save b, run_stats_save c&lt;br /&gt;                where a.name = b.name&lt;br /&gt;                  and b.name = c.name&lt;br /&gt;                  and a.runid = 'before'&lt;br /&gt;                  and b.runid = 'after 1'&lt;br /&gt;                  and c.runid = 'after 2'&lt;br /&gt;                  and a.name like 'LATCH%'&lt;br /&gt;         and a.hostname = g_host&lt;br /&gt;         and a.hostname = b.hostname&lt;br /&gt;         and a.hostname = c.hostname&lt;br /&gt;               )&lt;br /&gt;    ) loop&lt;br /&gt;        dbms_output.put_line( x.data );&lt;br /&gt;    end loop;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;-- select * from TABLE(runstats_pkg.rs_report);&lt;br /&gt;&lt;br /&gt;function rs_report( p_difference_threshold in number default 0, p_host in varchar2 default Null )&lt;br /&gt;return print_tab PIPELINED DETERMINISTIC&lt;br /&gt;as&lt;br /&gt;begin&lt;br /&gt;  g_host := substr(SYS_CONTEXT('USERENV','TERMINAL'),1,30);&lt;br /&gt;  g_ip := substr(SYS_CONTEXT('USERENV','IP_ADDRESS'),1,30);&lt;br /&gt;&lt;br /&gt;    g_run2 := (dbms_utility.get_time-g_start);&lt;br /&gt;&lt;br /&gt;    PIPE ROW&lt;br /&gt;    ( 'Run1 ran in ' || g_run1 || ' hsecs' );&lt;br /&gt;    PIPE ROW&lt;br /&gt;    ( 'Run2 ran in ' || g_run2 || ' hsecs' );&lt;br /&gt;    PIPE ROW&lt;br /&gt;    ( 'run 1 ran in ' || round(g_run1/g_run2*100,2) ||&lt;br /&gt;      '% of the time' );&lt;br /&gt;    PIPE ROW( chr(9) );&lt;br /&gt;&lt;br /&gt;    PIPE ROW&lt;br /&gt;    ( rpad( 'Name', 40 ) || lpad( 'Run1', 14 ) ||&lt;br /&gt;      lpad( 'Run2', 14 ) || lpad( 'Diff', 14 ) );&lt;br /&gt;&lt;br /&gt;    for x in&lt;br /&gt;    ( select rpad( a.name, 40 ) ||&lt;br /&gt;             to_char( b.value-a.value, '99999,999,999' ) ||&lt;br /&gt;             to_char( c.value-b.value, '99999,999,999' ) ||&lt;br /&gt;             to_char( ( (c.value-b.value)-(b.value-a.value)), '99999,999,999' ) data&lt;br /&gt;        from run_stats_save a, run_stats_save b, run_stats_save c&lt;br /&gt;       where a.name = b.name&lt;br /&gt;         and b.name = c.name&lt;br /&gt;         and a.runid = 'before'&lt;br /&gt;         and b.runid = 'after 1'&lt;br /&gt;         and c.runid = 'after 2'&lt;br /&gt;         -- and (c.value-a.value) &amp;gt; 0&lt;br /&gt;         and abs( (c.value-b.value) - (b.value-a.value) )&lt;br /&gt;               &amp;gt; p_difference_threshold&lt;br /&gt;         and a.hostname = g_host&lt;br /&gt;         and a.hostname = b.hostname&lt;br /&gt;         and a.hostname = c.hostname&lt;br /&gt;       order by abs( (c.value-b.value)-(b.value-a.value)), abs(c.value-b.value)&lt;br /&gt;    ) loop&lt;br /&gt;        PIPE ROW( x.data );&lt;br /&gt;    end loop;&lt;br /&gt;&lt;br /&gt;    PIPE ROW( chr(9) );&lt;br /&gt;    PIPE ROW&lt;br /&gt;    ( 'Run1 latches total versus run2 -- difference and pct' );&lt;br /&gt;    PIPE ROW&lt;br /&gt;    ( lpad( 'Run1', 14 ) || lpad( 'Run2', 14 ) ||&lt;br /&gt;      lpad( 'Diff', 14 ) || lpad( 'Pct', 11 ) );&lt;br /&gt;&lt;br /&gt;    for x in&lt;br /&gt;    ( select to_char( run1, '99999,999,999' ) ||&lt;br /&gt;             to_char( run2, '99999,999,999' ) ||&lt;br /&gt;             to_char( diff, '99999,999,999' ) ||&lt;br /&gt;             to_char( round( run1/run2*100,2 ), '99,999.99' ) || '%' data&lt;br /&gt;        from ( select sum(b.value-a.value) run1, sum(c.value-b.value) run2,&lt;br /&gt;                      sum( (c.value-b.value)-(b.value-a.value)) diff&lt;br /&gt;                 from run_stats_save a, run_stats_save b, run_stats_save c&lt;br /&gt;                where a.name = b.name&lt;br /&gt;                  and b.name = c.name&lt;br /&gt;                  and a.runid = 'before'&lt;br /&gt;                  and b.runid = 'after 1'&lt;br /&gt;                  and c.runid = 'after 2'&lt;br /&gt;                  and a.name like 'LATCH%'&lt;br /&gt;         and a.hostname = g_host&lt;br /&gt;         and a.hostname = b.hostname&lt;br /&gt;         and a.hostname = c.hostname&lt;br /&gt;               )&lt;br /&gt;    ) loop&lt;br /&gt;        PIPE ROW( x.data );&lt;br /&gt;    end loop;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;grant execute on utility.runstats_pkg to public;&lt;br /&gt;create or replace public synonym runstats_pkg for utility.runstats_pkg; &lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;--Usage: to benchmark two approaches&lt;br /&gt;--you may just leave approach 2 code part empty, to get resources of code 1 take.&lt;br /&gt;&lt;br /&gt;set serveroutput on&lt;br /&gt;&lt;br /&gt;execute runStats_pkg.rs_start;&lt;br /&gt; &lt;your 1="" approach="" code=""&gt;&lt;br /&gt;execute runStats_pkg.rs_middle;&lt;br /&gt; &lt;your 2="" approach="" code=""&gt;&lt;br /&gt;execute runStats_pkg.rs_stop;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;runStats_pkg.rs_start;&lt;br /&gt; for c in ()&lt;br /&gt; loop&lt;br /&gt;   Null;&lt;br /&gt; end loop;&lt;br /&gt;runStats_pkg.rs_middle;&lt;br /&gt; for c in ()&lt;br /&gt; loop&lt;br /&gt;   Null;&lt;br /&gt; end loop;&lt;br /&gt;runStats_pkg.rs_stop;&lt;br /&gt;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;--To get the report after benchmark:&lt;br /&gt;select * from TABLE(runstats_pkg.rs_report);&lt;br /&gt;OR&lt;br /&gt;exec runStats_pkg.rs_report(10);&lt;br /&gt;&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-2394250855386621351?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/2394250855386621351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=2394250855386621351' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/2394250855386621351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/2394250855386621351'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2010/05/benchmark-with-runstats.html' title='Benchmark with RunStats'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-1898397528889015516</id><published>2010-04-26T10:07:00.000-07:00</published><updated>2010-04-26T10:07:45.724-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>Find and delete duplicate rows by Analytic Function</title><content type='html'>The intuitive way will be create a temp table, with Min(&lt;a class="tiddlyLink tiddlyLinkNonExisting" href="file:///A:/design/wiki/mj2010wiki.html" refresh="link" tiddlylink="RowID" title="The tiddler 'RowID' doesn't yet exist"&gt;RowID&lt;/a&gt;) and Count(*)&amp;gt;1, then join it back to target table to do the delete.&lt;br /&gt;&lt;br /&gt;You can get duplicate rows by Analytic SQL:&lt;br /&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;SELECT rid, deptno, job, rn&lt;br /&gt;  FROM&lt;br /&gt;  (SELECT /*x parallel(a) */&lt;br /&gt;        ROWID rid, deptno, job,&lt;br /&gt;        ROW_NUMBER () OVER (PARTITION BY deptno, job ORDER BY empno) rn&lt;br /&gt;   FROM scott.emp a&lt;br /&gt;  )&lt;br /&gt;WHERE rn &amp;lt;&amp;gt; 1;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Get duplicate row count with Count(*) &amp;gt; 0.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SELECT /*x parallel(a,8) */&lt;br /&gt; MAX(ROWID) rid, deptno, job, COUNT(*)&lt;br /&gt;FROM scott.emp a&lt;br /&gt;GROUP BY deptno, job&lt;br /&gt;HAVING COUNT(*) &amp;gt; 1;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To delete them:&lt;br /&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;DELETE FROM scott.emp&lt;br /&gt;WHERE ROWID IN&lt;br /&gt; (&lt;br /&gt;  SELECT rid&lt;br /&gt;    FROM (SELECT /*x parallel(a) */&lt;br /&gt;                 ROWID rid, deptno, job,&lt;br /&gt;                 ROW_NUMBER () OVER (PARTITION BY deptno, job ORDER BY empno) rn&lt;br /&gt;            FROM scott.emp a)&lt;br /&gt;  WHERE rn &amp;lt;&amp;gt; 1&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-1898397528889015516?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/1898397528889015516/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=1898397528889015516' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/1898397528889015516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/1898397528889015516'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2010/04/find-and-delete-duplicate-rows-by.html' title='Find and delete duplicate rows by Analytic Function'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-4018961145747493540</id><published>2010-04-19T10:29:00.000-07:00</published><updated>2010-04-19T10:29:13.230-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>Reclaim deleted LOB data storage</title><content type='html'>I was helping a client purge obsolete data and reclaim some space in an OLAP database.&lt;br /&gt;We stuck on a BLOB column segment. It took me a couple hours to find the solution.&lt;br /&gt;&lt;br /&gt;Here is the solution demo.&lt;br /&gt;&lt;br /&gt;Create a table with BLOB column,&lt;br /&gt;&lt;pre&gt;drop table t2 purge;&lt;br /&gt;&lt;br /&gt;CREATE TABLE t2&lt;br /&gt;(&lt;br /&gt; n1 NUMBER(10),&lt;br /&gt; d1 date,&lt;br /&gt; b1 BLOB,&lt;br /&gt; CONSTRAINT t2_PK PRIMARY KEY (n1)&lt;br /&gt;  USING INDEX TABLESPACE index_auto&lt;br /&gt;) &lt;br /&gt;TABLESPACE data_auto;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;Displays the large objects (&lt;a class="tiddlyLink tiddlyLinkNonExisting" href="file:///A:/design/wiki/mj2010wiki.html" refresh="link" tiddlylink="LOBs" title="The tiddler 'LOBs' doesn't yet exist"&gt;LOBs&lt;/a&gt;) contained in tables&lt;br /&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;select b.TABLE_NAME, b.COLUMN_NAME, b.SEGMENT_NAME, b.TABLESPACE_NAME, b.INDEX_NAME&lt;br /&gt;from user_lobs b;&lt;br /&gt;&lt;br /&gt;SELECT SEGMENT_NAME, segment_type, TABLESPACE_NAME, BYTES, BLOCKS, EXTENTS&lt;br /&gt;FROM user_SEGMENTS&lt;br /&gt;WHERE segment_type like '%LOB%'&lt;br /&gt;ORDER BY SEGMENT_NAME;&lt;br /&gt;&lt;br /&gt;SELECT b.TABLE_NAME, b.COLUMN_NAME, b.SEGMENT_NAME, b.TABLESPACE_NAME, b.INDEX_NAME&lt;br /&gt; ,s.bytes, s.blocks, s.extents&lt;br /&gt;FROM user_lobs b, user_segments s&lt;br /&gt;WHERE b.table_name = 'T2'&lt;br /&gt;and b.column_name = 'B1'&lt;br /&gt;and s.segment_type like 'LOB%'&lt;br /&gt;and s.segment_name = b.segment_name;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Test Shrink a BASICFILE LOB segment only&lt;/h3&gt;&lt;pre&gt;truncate table t2;&lt;br /&gt;&lt;br /&gt;declare&lt;br /&gt;    l_blob blob;&lt;br /&gt;    l_size number := 32700;&lt;br /&gt;begin&lt;br /&gt;  for i in 1 .. 15&lt;br /&gt;  loop&lt;br /&gt;    insert into t2(n1,b1) values (i, empty_blob() ) returning b1 into l_blob;&lt;br /&gt;    dbms_lob.writeappend( l_blob, l_size, utl_raw.cast_to_raw(rpad('*',l_size,'*')));&lt;br /&gt;  end loop;&lt;br /&gt;  commit;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;delete t2;&lt;br /&gt;commit;&lt;br /&gt;&lt;br /&gt;SELECT b.TABLE_NAME, b.COLUMN_NAME, b.SEGMENT_NAME, b.TABLESPACE_NAME, b.INDEX_NAME&lt;br /&gt; ,s.bytes, s.blocks, s.extents&lt;br /&gt;FROM user_lobs b, user_segments s&lt;br /&gt;WHERE b.table_name = 'T2'&lt;br /&gt;and b.column_name = 'B1'&lt;br /&gt;and s.segment_type like 'LOB%'&lt;br /&gt;and s.segment_name = b.segment_name;&lt;br /&gt;&lt;br /&gt;     BYTES     BLOCKS    EXTENTS&lt;br /&gt;---------- ---------- ----------&lt;br /&gt;    720896         88         11&lt;br /&gt;&lt;br /&gt;ALTER TABLE t2 MODIFY LOB (b1) (SHRINK SPACE);&lt;br /&gt;&lt;br /&gt;SELECT b.TABLE_NAME, b.COLUMN_NAME, b.SEGMENT_NAME, b.TABLESPACE_NAME, b.INDEX_NAME&lt;br /&gt; ,s.bytes, s.blocks, s.extents&lt;br /&gt;FROM user_lobs b, user_segments s&lt;br /&gt;WHERE b.table_name = 'T2'&lt;br /&gt;and b.column_name = 'B1'&lt;br /&gt;and s.segment_type like 'LOB%'&lt;br /&gt;and s.segment_name = b.segment_name;&lt;br /&gt;&lt;br /&gt;     BYTES     BLOCKS    EXTENTS&lt;br /&gt;---------- ---------- ----------&lt;br /&gt;     65536          8          1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h2&gt;Note&lt;/h2&gt;Shrink command will generate about same size of redo/archive logs as LOB storage space size.&lt;br /&gt;&lt;h2&gt;Reference.&lt;/h2&gt;&lt;br /&gt;Shrink a table and all of its dependent segments (including BASICFILE LOB segments):&lt;br /&gt;&lt;pre&gt;ALTER TABLE t2 ENABLE ROW MOVEMENT;&lt;br /&gt;ALTER TABLE t2 SHRINK SPACE CASCADE;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Shrink a BASICFILE LOB segment only:&lt;br /&gt;&lt;pre&gt;ALTER TABLE t2 MODIFY LOB (b1) (SHRINK SPACE);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-4018961145747493540?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/4018961145747493540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=4018961145747493540' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/4018961145747493540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/4018961145747493540'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2010/04/reclaim-deleted-lob-data-storage.html' title='Reclaim deleted LOB data storage'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-7187436153226585862</id><published>2010-04-12T11:26:00.000-07:00</published><updated>2010-04-12T15:36:54.328-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>Pl/SQL Development Workflow</title><content type='html'>Here is the notes taking from book &amp;lt;&amp;lt;&lt;span class="Apple-style-span" style="font-size: 32px; font-weight: bold;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Oracle PL/SQL Best Practices&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&amp;gt;&amp;gt;.&lt;br /&gt;&lt;br /&gt;Four steps of preparing an application, special for PL/SQL&amp;nbsp;transactional&amp;nbsp;database API.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 24px; font-weight: bold;"&gt;Validate program requirements&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt; ask lots of questions&lt;/li&gt;&lt;li&gt; what users ask for is not always the easiest way to solve a problem&lt;/li&gt;&lt;li&gt; consider other approaches, include business processes and programming algorithms&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;Implement header of the program&lt;/h2&gt;&lt;ol&gt;&lt;li&gt; good name for the program, accurately represent the purpose of the program&lt;/li&gt;&lt;li&gt; inputs and outputs&lt;/li&gt;&lt;li&gt; overload sub-procedure ?&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;Define the test cases&lt;/h2&gt;&lt;ol&gt;&lt;li&gt; Verify it works&lt;/li&gt;&lt;li&gt; how will I know when I am done with this program&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;Build test code&lt;/h2&gt;&lt;div&gt;Testing for correctness:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Have you tested with good and all the different possibilities of bad data&lt;/li&gt;&lt;li&gt; Does the code do the right thing, ... and nothing more.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-7187436153226585862?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/7187436153226585862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=7187436153226585862' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/7187436153226585862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/7187436153226585862'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2010/04/plsql-development-workflow.html' title='Pl/SQL Development Workflow'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-827227717789454590</id><published>2010-04-06T15:28:00.000-07:00</published><updated>2010-10-22T14:17:50.240-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>Why Transactional Database API approach?</title><content type='html'>We like Transactional Database API approach, because it:&lt;br /&gt;&lt;br /&gt;1. make software components modular, I'm totally into modular programming&lt;br /&gt;2. software modules must carry out a very specific task&lt;br /&gt;(and be very efficient at carrying it out)&lt;br /&gt;3. each software module should be loosely coupled (to limit dependencies)&lt;br /&gt;4. It removes the need for triggers as all inserts, updates and deletes are wrapped in &lt;a class="tiddlyLink tiddlyLinkNonExisting" href="file:///A:/design/wiki/mj2010wiki.html" refresh="link" tiddlylink="APIs" title="The tiddler 'APIs' doesn't yet exist"&gt;APIs&lt;/a&gt;. Instead of writing triggers you simply add the code into the API. I loath triggers.&lt;br /&gt;5. It prevents people who don't understand SQL writing stupid queries.&lt;br /&gt;All SQL would be written by PL/SQL developers or DBAs, reducing the likelihood of dodgy queries.&lt;br /&gt;Profession = Efficiency + High Quality&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Anything that generates SQL on-the-fly worries me, not just Java. I want to be able to cut and paste the SQL, not try and capture or trace it during a run.&lt;/div&gt;&lt;br /&gt;6. The underlying structure of the database is hidden from the users, so I can make structural changes without client applications being changed.The API implementation can be altered and tuned without affecting the client application.&lt;br /&gt;7. The same &lt;a class="tiddlyLink tiddlyLinkNonExisting" href="file:///A:/design/wiki/mj2010wiki.html" refresh="link" tiddlylink="APIs" title="The tiddler 'APIs' doesn't yet exist"&gt;APIs&lt;/a&gt; are available to all applications that access the database. No duplication of effort.&lt;br /&gt;8. Eliminate SQL Parse in host language. Parse consume client host CPU and Server CPU and Latches. PL/SQL keep the SQL cursor cached and opened.&lt;br /&gt;9. Eliminate data round trip; data type conversion, the context switch.&lt;br /&gt;10. Tightly couple the data model and data process design, database world favor of Up Front Big Design.&lt;br /&gt;Maximum the data share and reuse.&lt;br /&gt;...&lt;br /&gt;This list goes on and on.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Our concept is "build the data API in the database, you call the data API".&lt;br /&gt;The &lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:672724700346558185#675813100346056247"&gt;data API&lt;/a&gt; encapsulate a transaction in a bit of code.  Here we agree - no  SQL in the client application, just call stored procedures - well tuned and developed  explicitly to do that one thing.&lt;br /&gt;&lt;br /&gt;Database API has been layered by different UI technologies over time.&lt;br /&gt;&lt;br /&gt;All about API's. The applications don't do table level(select/insert/update/delete) stuff, the apps don't even really know about tables.&lt;br /&gt;&lt;br /&gt;On top of database schema we have an API that does the data stuff.&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt;(generally, functions or Ref cursor to retrieve data, procedures to change data)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In the application we call this API but have our own application logic as well&lt;br /&gt;(only application logic is in the application, data logic is - well, right where it belongs - next to the data, waiting for the 'next great programming paradigm to come along')&lt;br /&gt;&lt;br /&gt;The fact that our UI is in Java isn't really relevant. You could pretty much see how you would use this package from C#, Java/JSP, Swing, VB, Pro*C, Forms, Powerbuilder, Perl, PHP, Python, a mobile phone, &amp;lt;whatever the heck you want&amp;gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-827227717789454590?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/827227717789454590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=827227717789454590' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/827227717789454590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/827227717789454590'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2010/04/why-transactional-database-api-approach.html' title='Why Transactional Database API approach?'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-102546898726732586</id><published>2010-03-29T13:51:00.000-07:00</published><updated>2010-03-29T14:06:23.523-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>Setup StatsPack to monitor standby database performance</title><content type='html'>AWR/ADDM are not supported (and don't work) against a read only standby database, so they are not useful for diagnostic for an Active Data Guard environment.&lt;br /&gt;&lt;br /&gt;A modifed version of statspack availabe on metalink (note 454848.1) can be deployed on the primary production database.  This modified version uses a STDBYPERF schema which writes locally but reads remotely from PERFSTAT@standbydb.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Initial Setup&lt;/span&gt; (Oracle 11.1.0.7)&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;export ORACLE_SID=standbydb&lt;br /&gt;cd $ORACLE_HOME/rdbms/admin&lt;br /&gt;sql&lt;br /&gt;CREATE SMALLFILE TABLESPACE PERFSTAT DATAFILE '+DATA1/perfstat01.dbf' SIZE 4G&lt;br /&gt; LOGGING &lt;br /&gt; EXTENT MANAGEMENT LOCAL &lt;br /&gt; SEGMENT SPACE MANAGEMENT AUTO;&lt;br /&gt;@spdrop&lt;br /&gt;@spcreate&lt;br /&gt;exit;&lt;br /&gt;&lt;br /&gt;sql&lt;br /&gt;@sbcreate&lt;br /&gt;&lt;br /&gt;--wait a second or two, the account has to propagate to the standby&lt;br /&gt;&lt;br /&gt;@sbaddins&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Configure Snapshots&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Remember that PERFSTAT is not automatically purged/managed by the database, so this must be done by the DBA or scheduled.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;-- workaround to avoid serious performance problem due to Bug 8323663&lt;br /&gt;. setdb ordprod2&lt;br /&gt;sql&lt;br /&gt;execute dbms_stats.gather_table_stats(ownname =&amp;gt; 'SYS',tabname =&amp;gt; 'X$KCCTS', estimate_percent =&amp;gt; 20 );&lt;br /&gt;execute dbms_stats.gather_table_stats(ownname =&amp;gt; 'SYS',tabname =&amp;gt; 'X$KCFIO', estimate_percent =&amp;gt; 20 );&lt;br /&gt;execute dbms_stats.gather_table_stats(ownname =&amp;gt; 'SYS',tabname =&amp;gt; 'X$KCBFWAIT', estimate_percent =&amp;gt; 20 );&lt;br /&gt;execute dbms_stats.gather_table_stats(ownname =&amp;gt; 'SYS',tabname =&amp;gt; 'X$KCCFN', estimate_percent =&amp;gt; 20 );&lt;br /&gt;execute dbms_stats.gather_table_stats(ownname =&amp;gt; 'SYS',tabname =&amp;gt; 'X$KCCFE', estimate_percent =&amp;gt; 20 );&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;grant create job to stdbyperf;&lt;br /&gt;grant manage scheduler to stdbyperf;&lt;br /&gt;&lt;br /&gt;conn stdbyperf/***&lt;br /&gt;&lt;br /&gt;-- if this takes more than ~40 seconds there is a performance issue that will need to be traced&lt;br /&gt;exec statspack_ordprod1.snap;&lt;br /&gt;&lt;br /&gt;-- automate stats collection every 30 min during Mon-Fri 7am-5pm&lt;br /&gt;&lt;br /&gt;exec dbms_scheduler.disable('ordrpt_statspack_snap_daily');&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;   dbms_scheduler.create_job&lt;br /&gt;   (&lt;br /&gt;      job_name =&amp;gt; 'ordrpt_statspack_snap_daily',&lt;br /&gt;      job_type =&amp;gt; 'PLSQL_BLOCK',&lt;br /&gt;      job_action =&amp;gt; 'begin statspack_ordprod1.snap; end;',&lt;br /&gt;      repeat_interval =&amp;gt; 'FREQ=MINUTELY; INTERVAL=30; BYHOUR=7,8,9,10,11,12,13,14,15,16,17; BYDAY=MON,TUE,WED,THU,FRI',&lt;br /&gt;      enabled =&amp;gt; true,&lt;br /&gt;      comments =&amp;gt; 'Take statspack snapshot on remote standby db ordrpt daily Mon to Fri 7am to 5pm'&lt;br /&gt;   );&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;exec dbms_scheduler.enable('ordrpt_statspack_snap_daily');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Create Reports&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Similar to AWR reports, run reports from caldbrac02&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SQL&amp;gt; conn stbyperf/***&lt;br /&gt;&lt;br /&gt;SQL&amp;gt; @?/rdbms/admin/sbreport&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;-- follows prompts to enter dbid, instanceid, snapshot intervals, output is text file&lt;br /&gt;&lt;br /&gt;Author:&amp;nbsp;&lt;b&gt;&lt;span style="font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 10.0pt;"&gt;Blair Boadway&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 10.0pt;"&gt;&amp;nbsp;&amp;nbsp;|&amp;nbsp;&amp;nbsp;Production DBA&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-102546898726732586?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/102546898726732586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=102546898726732586' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/102546898726732586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/102546898726732586'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2010/03/setup-statspack-to-monitor-standby.html' title='Setup StatsPack to monitor standby database performance'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-2150161206983157073</id><published>2010-03-16T12:28:00.000-07:00</published><updated>2010-03-17T10:58:37.678-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>Query paging row count</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="white-space: normal;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;div class="tiddler selected" dirty="false" id="tiddlerQueryPaging" refresh="tiddler" tags="UI Paging" template="ViewTemplate" tiddler="QueryPaging"&gt;&lt;div class="viewer"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Do we need to return the accurate query row count?&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;We will always evaluate the query performance and cost to get the row count, and based on function/features priority and data accuracy requirements, then decide which option to go.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Also assess which option list below that the end users value more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt; The quick response time to return the first page&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;span class="Apple-style-span"&gt;or&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt; to get the exact row count.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt; &lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Here are some options I know so far:&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt; &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Materialize the row count in MV(Summary table), schedule a regular job to refresh the summary data.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt; Estimate the row count, by CBO parse&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;span class="Apple-style-span"&gt;Here is the idea, check the plan output Rows column.&lt;br /&gt;&lt;br /&gt;The CBO (Cost Base Optimizer) estimate it when generate the SQL execution plan.&lt;br /&gt;CBO get it from object(table/index) stats, e.g. dba_tables.num_rows .&lt;br /&gt;But not touching the table.&lt;br /&gt;&lt;br /&gt;scott@txdev_FLURRY&amp;gt; set autot trace exp&lt;br /&gt;scott@txdev_FLURRY&amp;gt;&lt;br /&gt;scott@txdev_FLURRY&amp;gt; select * from emp;&lt;br /&gt;Elapsed: 00:00:00.01&lt;br /&gt;&lt;br /&gt;Execution Plan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;Plan hash value: 3956160932&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |&lt;br /&gt;--------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT  |      |    14 |   518 |     3   (0)| 00:00:01 |&lt;br /&gt;|   1 |  TABLE ACCESS FULL| EMP  |    14 |   518 |     3   (0)| 00:00:01 |&lt;br /&gt;--------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt; Estimate the row count, with oracles SAMPLE clause&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt; Hard limit in Transactional database API, &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Show user that there could be more rows than hard code limit, and always enable [Next Page] button, and dynamic change or increase the count number as paging forward.&lt;/span&gt;&lt;/blockquote&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="Apple-style-span"&gt;SELECT count(*) from scott.emp where rownum &amp;lt;= 100;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span class="Apple-style-span"&gt;.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-2150161206983157073?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/2150161206983157073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=2150161206983157073' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/2150161206983157073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/2150161206983157073'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2010/03/query-paging.html' title='Query paging row count'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-2302373208758711177</id><published>2010-03-10T10:44:00.000-08:00</published><updated>2010-03-10T10:44:37.559-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>SOA - Transactional Database API - Database access guideline</title><content type='html'>"Applications come, applications go, they crash, they change, they are fleeting."&lt;br /&gt;The data however -- that'll be here long.&lt;br /&gt;&lt;br /&gt;Programming language come, programming languages go, DBMSs come, DBMSs go,&lt;br /&gt;&lt;br /&gt;In fact, I've seen successful Cobol, Fortran, VB, Perl, PHP, Java, Python, whatever language; FoxPro, Sybase, DB2, Oracle, MySQL, Cassandra HBase, whatever database.&lt;br /&gt;&lt;br /&gt;The data, well, Our AbePOs(orders) and Clients data have been in a database for over 12 years now -- the applications that access (should say "have accessed in the past for they no longer exist") it come and they go and there will be many many many more in the future.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The solution is there: SOA (Modular programming)&lt;br /&gt;&lt;br /&gt;SOA is a design principle, whereas web services is an implementation technology. You can build a Service-Oriented Application with .Net, C, Java, or PL/SQL, T-SQL.&lt;br /&gt;&lt;br /&gt;The basic building block... is the service. A service is a self-contained software module that performs a predetermined task: e.g. a business transaction to submit order, audit the changes, update inventory, update finance data, queue the changes to asynchronous batch notice buyers ...; that comes to the Transactional database API.&lt;br /&gt;&lt;br /&gt;The main theme behind SOA is to find the appropriate modularity ... where the modules don't have too much tight coupling. such as UI, Business rule and DAL.&lt;br /&gt;&lt;br /&gt;An typical bad example is the Buyer Order Tracker UI, the reporting UI rule is tightly coupled with data access, make it so hard to refactor the data access part. BOT has made database performance plunged many times.&lt;br /&gt;&lt;br /&gt;If we implement the SOA, the database handle the data access, and the Java handle the UI, it'll be a piece of cake to fix the BOT database performance issue.&lt;br /&gt;&lt;br /&gt;When we want to migrate to Sybase, just write a new DB API on Sybase, UI application call the new API.&lt;br /&gt;When we want to migrate to .Net, just write a new UI module, that calls the same DB API to access the data.&lt;br /&gt;&lt;br /&gt;Notes: many statements are referenced from &lt;a href="http://asktom.oracle.com"&gt;AskTom&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-2302373208758711177?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/2302373208758711177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=2302373208758711177' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/2302373208758711177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/2302373208758711177'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2010/03/soa-transactional-database-api-database.html' title='SOA - Transactional Database API - Database access guideline'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-7988098807467019601</id><published>2009-12-07T10:44:00.001-08:00</published><updated>2009-12-07T10:45:28.701-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>Turn on INTERVAL PARTITIONING on a range partition table</title><content type='html'>Create a range partition table.&lt;br /&gt;&lt;br /&gt;SQL:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;drop _TABLE_ date_range_t purge;&lt;br /&gt;&lt;br /&gt;CREATE TABLE date_range_t&lt;br /&gt;(  &lt;br /&gt;d1   DATE,&lt;br /&gt;n1   NUMBER&lt;br /&gt;) &lt;br /&gt;PARTITION BY RANGE ( d1 ) &lt;br /&gt;SUBPARTITION BY LIST ( n1 ) &lt;br /&gt;SUBPARTITION TEMPLATE ( &lt;br /&gt;SUBPARTITION s_1    VALUES ( 1,2 ) , &lt;br /&gt;SUBPARTITION s_2    VALUES ( 3,4 ) &lt;br /&gt;)&lt;br /&gt;( PARTITION p200911  VALUES LESS THAN ( TO_DATE('2009/12/01', 'YYYY/MM/DD') )&lt;br /&gt;)&lt;br /&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Turn on INTERVAL PARTITIONING by month on a range partition table.&lt;br /&gt;&lt;br /&gt;SQL:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;ALTER TABLE date_range_t SET INTERVAL ( NUMTOYMINTERVAL ( 1, 'MONTH' ) );&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-7988098807467019601?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/7988098807467019601/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=7988098807467019601' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/7988098807467019601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/7988098807467019601'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/12/turn-on-interval-partitioning-on-range.html' title='Turn on INTERVAL PARTITIONING on a range partition table'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-4224465972143514133</id><published>2009-11-18T14:29:00.001-08:00</published><updated>2011-06-08T14:27:01.072-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>Effective table selectivity index selectivity and index column sequence</title><content type='html'>/*********&lt;br /&gt;-- file://A:/SQL/CBO/index_selectivity.sql&lt;br /&gt;&lt;br /&gt;| Modification History:&lt;br /&gt;|   Date       Who          What&lt;br /&gt;| 18-Nov-2009: Charlie(Yi): Create the file,&lt;br /&gt;|&lt;br /&gt;&lt;br /&gt;Effective table selectivity selectivity and index column sequence&lt;br /&gt;&lt;br /&gt;Goal&lt;br /&gt;----&lt;br /&gt;Research the order of the index columns and the effective index selectivity.&lt;br /&gt;&lt;br /&gt;Solution&lt;br /&gt;--------&lt;br /&gt;Create a table with number column and date column, &lt;br /&gt;Create 2 indexes on the table, one with ID in index first position, one with date_col on first position.&lt;br /&gt;Benchmark the query with equal scan and range scan predicate on each index.&lt;br /&gt;&lt;br /&gt;Outcome&lt;br /&gt;-------&lt;br /&gt;The logical reads on index access is: BLevel + leaf_blocks * effective index selectivity.&lt;br /&gt;&lt;br /&gt;* LIO is 5  when access index with column ID on first position&lt;br /&gt;select 2 + Ceil(1520 * 0.2 * (40 * 100)/500000) from dual;&lt;br /&gt;&lt;br /&gt;* LIO is 15 when access index with date_col on first position,&lt;br /&gt;select 2 + Ceil(1520 * (40 * 100)/500000) from dual;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;"Because as soon as we have a range scan on a column used somewhere in the&lt;br /&gt;middle of an index definition or fail to supply a test on such a column, the predicates on later&lt;br /&gt;columns don’t restrict the selection of index leaf blocks that we have to examine."&lt;br /&gt;&lt;br /&gt;From page74 of book Cost Based Oracle Fundamentals&lt;br /&gt;&lt;br /&gt;For 2nd query, the effective index selectivity has to be calculated from the predicate on just the&lt;br /&gt;date_col column. Because the test on date_col is range-based, the predicates on ID do not&lt;br /&gt;restrict the number of index leaf blocks we have to walk.&lt;br /&gt;&lt;br /&gt;Note&lt;br /&gt;----&lt;br /&gt;In plan output, Buffers = Logical Reads.&lt;br /&gt;&lt;br /&gt;*******/&lt;br /&gt;&lt;br /&gt;Setup&lt;br /&gt;-----&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;create table date_index_sel&lt;br /&gt;(&lt;br /&gt;id number,&lt;br /&gt;date_col date,&lt;br /&gt;n2 number&lt;br /&gt;)&lt;br /&gt;nologging;&lt;br /&gt;&lt;br /&gt;insert --+ append&lt;br /&gt;into date_index_sel(id,date_col)&lt;br /&gt;select mod(rownum,5), sysdate + rownum/100&lt;br /&gt;from dual&lt;br /&gt;connect by level &amp;lt;= 500000;&lt;br /&gt;&lt;br /&gt;commit;&lt;br /&gt;&lt;br /&gt;create index date_index_sel_i1 on date_index_sel(id,date_col) nologging;&lt;br /&gt;create index date_index_sel_i2 on date_index_sel(date_col,id) nologging;&lt;br /&gt;&lt;br /&gt;exec dbms_stats.gather_table_stats(user,'date_index_sel');&lt;br /&gt;&lt;br /&gt;select INDEX_NAME, BLEVEL, LEAF_BLOCKS, DISTINCT_KEYS, CLUSTERING_FACTOR, NUM_ROWS&lt;br /&gt;from user_indexes&lt;br /&gt;where index_name like 'DATE_INDEX_SEL%';&lt;br /&gt;&lt;br /&gt;INDEX_NAME BLEVEL LEAF_BLOCKS DISTINCT_KEYS CLUSTERING_FACTOR NUM_ROWS&lt;br /&gt;&lt;br /&gt;DATE_INDEX_SEL_I1 2 1520 500000 5475 500000&lt;br /&gt;DATE_INDEX_SEL_I2 2 1520 500000 1095 500000&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;set serveroutput off&lt;br /&gt;set linesize 370&lt;br /&gt;set pagesize 0&lt;br /&gt;&lt;br /&gt;REM TEST1, date_col is NOT the first index column, range scan on date_col,&lt;br /&gt;&lt;br /&gt;select --+ index(a,date_index_sel_i1) gather_plan_statistics&lt;br /&gt;count(*) from date_index_sel a&lt;br /&gt;where id=3 &lt;br /&gt;and date_col between sysdate + 100 and sysdate + 140;&lt;br /&gt;&lt;br /&gt;--SELECT * FROM table(dbms_xplan.display_cursor(NULL,NULL, 'basic iostats memstats last partition'));&lt;br /&gt;SELECT * FROM table(dbms_xplan.display_cursor(NULL,NULL, 'basic cost allstats last partition'));&lt;br /&gt;&lt;br /&gt;Plan hash value: 341633530&lt;br /&gt;&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation          | Name              |Cost (%CPU)| A-Rows | Buffers |&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT   |                   |    3 (100)|      1 |       5 |&lt;br /&gt;|   1 |  SORT AGGREGATE    |                   |           |      1 |       5 |&lt;br /&gt;|*  2 |   FILTER           |                   |           |    800 |       5 |&lt;br /&gt;|*  3 |    INDEX RANGE SCAN| DATE_INDEX_SEL_I1 |    3   (0)|    800 |       5 |&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   2 - filter(SYSDATE+100&amp;lt;=SYSDATE+140)&lt;br /&gt;   3 - access("ID"=3 AND "DATE_COL"&amp;gt;=SYSDATE+100 AND "DATE_COL"&amp;lt;=SYSDATE+140)&lt;br /&gt;&lt;br /&gt;REM TEST2, date_col is the first index column,&lt;br /&gt;&lt;br /&gt;select --+ index(a,date_index_sel_i2) gather_plan_statistics&lt;br /&gt;count(*) from date_index_sel a&lt;br /&gt;where id=3 &lt;br /&gt;and date_col between sysdate + 100 and sysdate + 140&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;SELECT * FROM table(dbms_xplan.display_cursor(NULL,NULL, 'basic cost iostats memstats last partition'));&lt;br /&gt;&lt;br /&gt;Plan hash value: 1386725119&lt;br /&gt;&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation          | Name              | Cost (%CPU)|A-Rows | Buffers |&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT   |                   |    15 (100)|     1 |      15 |&lt;br /&gt;|   1 |  SORT AGGREGATE    |                   |            |     1 |      15 |&lt;br /&gt;|*  2 |   FILTER           |                   |            |   800 |      15 |&lt;br /&gt;|*  3 |    INDEX RANGE SCAN| DATE_INDEX_SEL_I2 |    15   (0)|   800 |      15 |&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   2 - filter(SYSDATE+100&amp;lt;=SYSDATE+140)&lt;br /&gt;   3 - access("DATE_COL"&amp;gt;=SYSDATE+100 AND "ID"=3 AND "DATE_COL"&amp;lt;=SYSDATE+140)&lt;br /&gt;       filter("ID"=3)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;***.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-4224465972143514133?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/4224465972143514133/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=4224465972143514133' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/4224465972143514133'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/4224465972143514133'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/11/effective-table-selectivity-selectivity.html' title='Effective table selectivity index selectivity and index column sequence'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-5211854106599665578</id><published>2009-11-15T21:42:00.000-08:00</published><updated>2009-11-15T21:54:47.266-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>row level timestamp implementation</title><content type='html'>Goal&lt;br /&gt;----&lt;br /&gt;Identify latest row in one Bulk SQL INSERT, &lt;br /&gt;e.g. JDBC Update Batching, Batch Value is 1000,&lt;br /&gt;or PL/SQL FORALL statement.&lt;br /&gt;&lt;br /&gt;Case&lt;br /&gt;----&lt;br /&gt;One Bulk SQL insert 1000 rows, select from an Oracle external table,&lt;br /&gt;De-duplicate by primary key, identify latest row in the file.&lt;br /&gt;&lt;br /&gt;Constraint: All rows get same SCN or timestamp value if they are in one INSERT SQL.&lt;br /&gt;&lt;br /&gt;Solution&lt;br /&gt;-- -- ---&lt;br /&gt;plain simple Oracle Sequence, for row update timestamp implementation.&lt;br /&gt;&lt;br /&gt;drop table t purge;&lt;br /&gt;create table t(id number, ts timestamp(6), seq number);&lt;br /&gt;drop sequence s;&lt;br /&gt;create sequence s;&lt;br /&gt;&lt;br /&gt;declare&lt;br /&gt;  lt_id dbms_sql.number_table;&lt;br /&gt;begin&lt;br /&gt;  select rownum bulk collect into lt_id&lt;br /&gt;  from dual&lt;br /&gt;  connect by level &lt;= 10;&lt;br /&gt; &lt;br /&gt; forall i in 1..lt_id.count&lt;br /&gt; insert into t(id, ts)&lt;br /&gt; values(lt_id(i), systimestamp);&lt;br /&gt; &lt;br /&gt; commit;&lt;br /&gt; &lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;select id, ts from t;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;-- With update_change_sequence&lt;br /&gt;&lt;br /&gt;declare&lt;br /&gt;  lt_id dbms_sql.number_table;&lt;br /&gt;begin&lt;br /&gt;  select rownum bulk collect into lt_id&lt;br /&gt;  from dual&lt;br /&gt;  connect by level &lt;= 10;&lt;br /&gt; &lt;br /&gt; forall i in 1..lt_id.count&lt;br /&gt; insert into t(id, ts, seq)&lt;br /&gt; values(lt_id(i), systimestamp, s.nextval );&lt;br /&gt; &lt;br /&gt; commit;&lt;br /&gt; &lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;select id, seq, ts from t;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-5211854106599665578?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/5211854106599665578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=5211854106599665578' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/5211854106599665578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/5211854106599665578'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/11/row-level-timestamp-implementation.html' title='row level timestamp implementation'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-4352393310715217165</id><published>2009-11-11T21:21:00.001-08:00</published><updated>2009-11-18T17:38:18.185-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>Tune SQL with SQL plan baseline</title><content type='html'>Goal&lt;br /&gt;----&lt;br /&gt;Tune SQL plan without change the source code(SQL text),&lt;br /&gt;&lt;br /&gt;A:\SQL\CBO\tune_sql_by_baseline01.sql&lt;br /&gt;&lt;br /&gt;| Modification History:&lt;br /&gt;|   Date       Who          What&lt;br /&gt;| 11-Nov-2009: Charlie(Yi): Create the file,&lt;br /&gt;| 18-Nov-2009: Charlie(Yi): Show binding variable value,&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Solution&lt;br /&gt;--------&lt;br /&gt;* tune SQL execution plan by SQL plan baseline, load_plans_from_cursor_cache to &lt;br /&gt;  load the hint/changed resulting plan(s) into the SQL plan baseline of the original SQL statement,&lt;br /&gt;&lt;br /&gt;Step&lt;br /&gt;----&lt;br /&gt;&lt;br /&gt;REM display current "bad" sql plan,&lt;br /&gt;&lt;br /&gt;SQL&gt;&lt;br /&gt;set serveroutput off&lt;br /&gt;set linesize 300&lt;br /&gt;&lt;br /&gt;var l_bad_sql_id varchar2(30);&lt;br /&gt;var l_sql_text varchar2(200);&lt;br /&gt;exec :l_bad_sql_id := 'cbzfmb3mc9047';&lt;br /&gt;exec :l_sql_text := q'{FROM WANTS WHERE CLIENTID = :1 AND ROWDF = 'F' AND UPPERTITLE &gt;= :2}';&lt;br /&gt;&lt;br /&gt;REM 2nd option to get SQL_ID,&lt;br /&gt;SELECT b.executions EXEC,  INST_ID, b.sql_id, CHILD_NUMBER,&lt;br /&gt;ROUND(b.ROWS_PROCESSED/b.executions,1) rows_per,&lt;br /&gt; ROUND(b.BUFFER_GETS/b.executions,1) gets_per,&lt;br /&gt; ROUND(b.ELAPSED_TIME/b.executions/1000000,3) ela_per, &lt;br /&gt; b.module, parse_calls, first_load_time, disk_reads, &lt;br /&gt; b.sql_text&lt;br /&gt;FROM gv$sql b&lt;br /&gt;WHERE UPPER(b.sql_text) LIKE UPPER('%'||:l_sql_text||'%')&lt;br /&gt;  AND b.executions &gt; 0&lt;br /&gt;  and b.sql_text not like 'SELECT b.executions EXEC%'&lt;br /&gt;ORDER BY b.executions DESC;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;select * from table(dbms_xplan.display_awr(sql_id=&gt;:l_bad_sql_id, format=&gt;'basic rows cost partition note last'));&lt;br /&gt;&lt;br /&gt;or&lt;br /&gt;&lt;br /&gt;select * from table(dbms_xplan.display_cursor(sql_id=&gt;:l_bad_sql_id, format=&gt;'basic rows cost partition note last'));&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;----------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;SQL_ID cbzfmb3mc9047&lt;br /&gt;--------------------&lt;br /&gt;SELECT * FROM WANTS WHERE CLIENTID = :1 AND ROWDF = 'F' AND UPPERTITLE &gt;= :2 ORDER BY UPPERTITLE;&lt;br /&gt;&lt;br /&gt;Plan hash value: 1289812832&lt;br /&gt;&lt;br /&gt;----------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                   | Name            | Rows  | Cost (%CPU)|&lt;br /&gt;----------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT            |                 |       |   363 (100)|&lt;br /&gt;|   1 |  TABLE ACCESS BY INDEX ROWID| WANTS           | 38233 |   363   (0)|&lt;br /&gt;|   2 |   INDEX RANGE SCAN          | WANTSUPPERTITLE |   530 |    12   (0)|&lt;br /&gt;----------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;REM - show binding variable value,&lt;br /&gt;select name, position,datatype_string, last_captured, value_string, b.child_address, b.address&lt;br /&gt;from v$sql_bind_capture b&lt;br /&gt;where sql_id = :l_bad_sql_id&lt;br /&gt;and was_captured &lt;&gt; 'NO';&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;REM create sql plan baseline for the SQL,&lt;br /&gt;&lt;br /&gt;declare&lt;br /&gt; l_pls number;&lt;br /&gt;begin&lt;br /&gt; l_pls := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE (&lt;br /&gt;   sql_id            =&gt; :l_bad_sql_id,&lt;br /&gt;   plan_hash_value   =&gt; NULL,&lt;br /&gt;   fixed             =&gt; 'NO',&lt;br /&gt;   enabled           =&gt; 'NO'&lt;br /&gt; );&lt;br /&gt; u$err.trc('Number of plans loaded:'||l_pls);&lt;br /&gt;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;REM get sql text, sql_handle&lt;br /&gt;select sql_text, sql_handle, plan_name, enabled, accepted, fixed, autopurge from dba_sql_plan_baselines&lt;br /&gt;where sql_text like '%'||:l_sql_text||'%';&lt;br /&gt;&lt;br /&gt;var l_sql_handle varchar2(30);&lt;br /&gt;exec :l_sql_handle := 'SYS_SQL_ce7588e9ccd926d0';&lt;br /&gt;&lt;br /&gt;REM change sql hint to tune SQL execution plan,&lt;br /&gt;set serveroutput off&lt;br /&gt;set linesize 300&lt;br /&gt;var l_sql_id varchar2(30);&lt;br /&gt;var l_sql_plan_hash_value number;&lt;br /&gt;var l_sql_child_number number;&lt;br /&gt;&lt;br /&gt;var B1 number;&lt;br /&gt;exec :B1 := 123;&lt;br /&gt;var B2 varchar2(30);&lt;br /&gt;exec :B2 := '1S &amp; 2ND KINGS';&lt;br /&gt;&lt;br /&gt;SELECT --+ index_rs_asc(wants WANTSCLIENTID) &lt;br /&gt;* FROM WANTS WHERE CLIENTID = :B1 AND ROWDF = 'F' AND UPPERTITLE &gt;= :B2 ORDER BY UPPERTITLE;&lt;br /&gt;&lt;br /&gt;REM capture new SQL_ID and plan_hash_value,&lt;br /&gt;begin&lt;br /&gt;with m as (select sid from v$mystat where rownum &lt;= 1)&lt;br /&gt;select prev_sql_id, prev_child_number&lt;br /&gt; into :l_sql_id, :l_sql_child_number&lt;br /&gt;from m, v$session s&lt;br /&gt;where s.sid = m.sid;&lt;br /&gt;select plan_hash_value into :l_sql_plan_hash_value from v$sql&lt;br /&gt;where sql_id = :l_sql_id&lt;br /&gt;and rownum &lt;= 1;&lt;br /&gt;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;print :l_sql_id;&lt;br /&gt;print :l_sql_plan_hash_value;&lt;br /&gt;print :l_sql_child_number;&lt;br /&gt;&lt;br /&gt;REM verify the new SQL plan,&lt;br /&gt;select * from table(dbms_xplan.display_cursor(sql_id=&gt;:l_sql_id, cursor_child_no=&gt;:l_sql_child_number,&lt;br /&gt;format=&gt;'basic rows cost partition note last'));&lt;br /&gt;&lt;br /&gt;REM load new sql plan into plan baseline, with same sql_handle,&lt;br /&gt;declare&lt;br /&gt; l_pls number;&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt; l_pls := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE (&lt;br /&gt;   sql_id            =&gt; :l_sql_id,&lt;br /&gt;   plan_hash_value   =&gt; :l_sql_plan_hash_value,&lt;br /&gt;   sql_handle        =&gt; :l_sql_handle,&lt;br /&gt;   fixed             =&gt; 'NO',&lt;br /&gt;   enabled           =&gt; 'NO'&lt;br /&gt; );&lt;br /&gt; u$err.trc('Number of plans:'||l_pls);&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;REM display sql plan baseline,&lt;br /&gt;SELECT *&lt;br /&gt;FROM table(dbms_xplan.display_sql_plan_baseline(&lt;br /&gt; sql_handle =&gt; :l_sql_handle,&lt;br /&gt; format =&gt; 'typical'&lt;br /&gt;))&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;SQL handle: SYS_SQL_ce7588e9ccd926d0&lt;br /&gt;SQL text: SELECT * FROM WANTS WHERE CLIENTID = :1 AND ROWDF = 'F' AND UPPERTITLE&lt;br /&gt;          &gt;= :2 ORDER BY UPPERTITLE&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;Plan name: SYS_SQL_PLAN_ccd926d0604f1815&lt;br /&gt;Enabled: NO      Fixed: NO      Accepted: YES     Origin: MANUAL-LOAD&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Plan hash value: 1289812832&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                   | Name            | Rows  | Bytes | Cost (%CPU)| Time     |&lt;br /&gt;-----------------------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT            |                 |     1 |   217 | 17021   (1)| 00:03:08 |&lt;br /&gt;|*  1 |  TABLE ACCESS BY INDEX ROWID| WANTS           |     1 |   217 | 17021   (1)| 00:03:08 |&lt;br /&gt;|*  2 |   INDEX RANGE SCAN          | WANTSUPPERTITLE | 19756 |       |   361   (0)| 00:00:04 |&lt;br /&gt;-----------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   1 - filter("CLIENTID"=TO_NUMBER(:1) AND "ROWDF"='F')&lt;br /&gt;   2 - access("UPPERTITLE"&gt;=:2)&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;Plan name: SYS_SQL_PLAN_ccd926d0ff894fe1&lt;br /&gt;Enabled: YES     Fixed: YES     Accepted: YES     Origin: MANUAL-LOAD&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Plan hash value: 1555025420&lt;br /&gt;&lt;br /&gt;----------------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                    | Name          | Rows  | Bytes | Cost (%CPU)| Time     |&lt;br /&gt;----------------------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT             |               |     1 |   217 |     8  (13)| 00:00:01 |&lt;br /&gt;|   1 |  SORT ORDER BY               |               |     1 |   217 |     8  (13)| 00:00:01 |&lt;br /&gt;|*  2 |   TABLE ACCESS BY INDEX ROWID| WANTS         |     1 |   217 |     7   (0)| 00:00:01 |&lt;br /&gt;|*  3 |    INDEX RANGE SCAN          | WANTSCLIENTID |     7 |       |     3   (0)| 00:00:01 |&lt;br /&gt;----------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   2 - filter("UPPERTITLE"&gt;=:2 AND "ROWDF"='F')&lt;br /&gt;   3 - access("CLIENTID"=TO_NUMBER(:1))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;REM enable new plan in plan baseline,&lt;br /&gt;REM changes an attribute of a single plan or all plans,&lt;br /&gt;declare&lt;br /&gt; l_pls number;&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt; l_pls := dbms_spm.ALTER_SQL_PLAN_BASELINE( &lt;br /&gt;   sql_handle        =&gt; :l_sql_handle,&lt;br /&gt;   plan_name         =&gt; 'SYS_SQL_PLAN_ccd926d0ff894fe1',&lt;br /&gt;   attribute_name =&gt; 'enabled', &lt;br /&gt;   attribute_value =&gt; 'YES'&lt;br /&gt; );&lt;br /&gt; u$err.trc('Number of plans:'||l_pls);&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;REM fixed new plan in plan baseline,&lt;br /&gt;REM if it is realy a good plan,&lt;br /&gt;declare&lt;br /&gt; l_pls number;&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt; l_pls := dbms_spm.ALTER_SQL_PLAN_BASELINE( &lt;br /&gt;   sql_handle        =&gt; :l_sql_handle,&lt;br /&gt;   plan_name         =&gt; 'SYS_SQL_PLAN_ccd926d0ff894fe1',&lt;br /&gt;   attribute_name =&gt; 'fixed', &lt;br /&gt;   attribute_value =&gt; 'YES'&lt;br /&gt; );&lt;br /&gt; u$err.trc('Number of plans:'||l_pls);&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;REM verify attribute ENABLED and FIXED,&lt;br /&gt;select sql_text, sql_handle, plan_name, enabled, accepted, fixed, autopurge &lt;br /&gt;from dba_sql_plan_baselines&lt;br /&gt;where sql_handle = :l_sql_handle;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;REM verify new plan is picked up by CBO optimizer,&lt;br /&gt;explain plan for &lt;br /&gt;SELECT * FROM WANTS WHERE CLIENTID = :1 AND ROWDF = 'F' AND UPPERTITLE &gt;= :2 ORDER BY UPPERTITLE;&lt;br /&gt;&lt;br /&gt;select * from table(dbms_xplan.display());&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-4352393310715217165?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/4352393310715217165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=4352393310715217165' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/4352393310715217165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/4352393310715217165'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/11/tune-sql-with-sql-plan-baseline.html' title='Tune SQL with SQL plan baseline'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-5675856919052490369</id><published>2009-06-01T17:01:00.000-07:00</published><updated>2011-08-13T21:07:52.517-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>single INSERT vs array BULK INSERT</title><content type='html'>Goal&lt;br /&gt;----&lt;br /&gt;Compare the performance of single INSERT vs array BULK INSERT.&lt;br /&gt;&lt;br /&gt;Result&lt;br /&gt;------&lt;br /&gt;After you run benchmark a few more times, you will get about same result as I saw.&lt;br /&gt;&lt;br /&gt;Bulk DML spend 20% more CPU time,&lt;br /&gt;Latches are about same. No big difference.&lt;br /&gt;db block gets, physical reads, consistent gets, session logical reads are all about same.&lt;br /&gt;Bulk DML take 2MB more session pga memory is expected, to cache association array (1200 bytes * 1000 rows) in shared_pool memory. no big deal.&lt;br /&gt;&lt;br /&gt;Conclusion&lt;br /&gt;-----------&lt;br /&gt;Consider single SQL first.&lt;br /&gt;Only when the&amp;nbsp;data process logic is too complicated, we may&amp;nbsp;go with Bulk DML, there will be a little performance impact, e.g. 20% more CPU used.&lt;br /&gt;&lt;br /&gt;Notes: Thanks for Tom Kyte pointing out the design&amp;nbsp;strategy.&lt;br /&gt;(&lt;a href="http://mujiang.blogspot.com/2011/06/question-to-asktom-in-oracle-magazine.html"&gt;http://mujiang.blogspot.com/2011/06/question-to-asktom-in-oracle-magazine.html&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Reference&lt;br /&gt;---------&lt;br /&gt;Oracle® Database PL/SQL Language Reference&lt;br /&gt;11g Release 1 (11.1)&lt;br /&gt;12 Tuning PL/SQL Applications for Performance&lt;br /&gt;&lt;br /&gt;Reducing Loop Overhead for DML Statements and Queries with Bulk SQL.&lt;br /&gt;&lt;br /&gt;* Running One DML Statement Multiple Times (FORALL Statement)&lt;br /&gt;* Retrieving Query Results into Collections (BULK COLLECT Clause)&lt;br /&gt;&lt;br /&gt;Setup&lt;br /&gt;-----&lt;br /&gt;&lt;pre&gt;drop table listing_wide purge;&lt;br /&gt;create table listing_wide&lt;br /&gt;(&lt;br /&gt;vendor_id   number(10,0)  Not Null ,&lt;br /&gt;listing_id   number(20,0)  Not Null ,&lt;br /&gt;match_col               varchar2(1)     Not Null ,&lt;br /&gt;vendor_listing_id  VarChar2(40)  Not Null ,&lt;br /&gt;hash_lite         varchar2(32) ,&lt;br /&gt;hash_code  VarChar2(32) ,&lt;br /&gt;qty   number(5,0)  Not Null  ,&lt;br /&gt;price  number(10,2) Not Null  ,&lt;br /&gt;create_date Date default sysdate Not Null ,&lt;br /&gt;update_date Date default sysdate Not Null ,&lt;br /&gt;bsa_vend  Varchar2(30)     ,&lt;br /&gt;isbn_raw  Varchar2(25)             ,&lt;br /&gt;subject  Varchar2(2000)    ,&lt;br /&gt;author   varchar2(750)     ,&lt;br /&gt;title  varchar2(750)   ,&lt;br /&gt;vend_catalog varchar2(255)   ,&lt;br /&gt;description varchar2(4000) &lt;br /&gt;)&lt;br /&gt;NOLOGGING&lt;br /&gt;PARTITION BY LIST (vendor_id) &lt;br /&gt;(  &lt;br /&gt;PARTITION v2134736  values( 2134736 ),&lt;br /&gt;PARTITION v8408184  values( 8408184 ),&lt;br /&gt;PARTITION v1  values( 1 ),&lt;br /&gt;PARTITION v2  values( 2 ),&lt;br /&gt;PARTITION vendor_NULL  VALUES (NULL),&lt;br /&gt;PARTITION vendor_small VALUES (DEFAULT)&lt;br /&gt;)&lt;br /&gt;NOCOMPRESS &lt;br /&gt;NOPARALLEL&lt;br /&gt;ENABLE ROW MOVEMENT;&lt;br /&gt;&lt;br /&gt;drop table listing_purge;&lt;br /&gt;create table listing_purge&lt;br /&gt;NOLOGGING&lt;br /&gt;PARTITION BY LIST (vendor_id) &lt;br /&gt;(  &lt;br /&gt;PARTITION v2134736  values( 2134736 ),&lt;br /&gt;PARTITION v8408184  values( 8408184 ),&lt;br /&gt;PARTITION v1  values( 1 ),&lt;br /&gt;PARTITION v2  values( 2 ),&lt;br /&gt;PARTITION vendor_NULL  VALUES (NULL),&lt;br /&gt;PARTITION vendor_small VALUES (DEFAULT)&lt;br /&gt;)&lt;br /&gt;as&lt;br /&gt;select a.* &lt;br /&gt;from listing_wide a&lt;br /&gt;where 1=0;&lt;br /&gt;&lt;br /&gt;alter table listing_purge modify (&lt;br /&gt;create_date Date default sysdate ,&lt;br /&gt;update_date Date default sysdate &lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Test&lt;br /&gt;----&lt;br /&gt;&lt;br /&gt;truncate table listing_wide;&lt;br /&gt;truncate table listing_purge;&lt;br /&gt;&lt;br /&gt;insert /*+ append */ into listing_purge &lt;br /&gt;(listing_id, vendor_id, price, qty,hash_lite, hash_code, vendor_listing_id, author, title,subject,isbn_raw, bsa_vend&lt;br /&gt;,match_col)&lt;br /&gt;select&lt;br /&gt;rownum listing_id, &lt;br /&gt;mod(rownum,2) + 1 vendor_id,&lt;br /&gt;1.11 price,&lt;br /&gt;10 qty,&lt;br /&gt;rpad('x',31,'x') hash_lite,&lt;br /&gt;rpad('x',31,'x') hash_code,&lt;br /&gt;rownum vendor_listing_id,&lt;br /&gt;rpad(rownum,400,'x') author,&lt;br /&gt;rpad('x',400,'x') title,&lt;br /&gt;rpad('x',300,'x') subject,&lt;br /&gt;rownum isbn_raw,&lt;br /&gt;mod(rownum,100)||','||mod(Round(rownum/10),100) bsa_vend&lt;br /&gt;,'x' match_col&lt;br /&gt;from dual&lt;br /&gt;connect by level &amp;lt;= 80100;&lt;br /&gt;&lt;br /&gt;commit;&lt;br /&gt;&lt;br /&gt;set serveroutput on&lt;br /&gt;set linesize 200&lt;br /&gt;begin&lt;br /&gt;tmp_benchmark;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;select vendor_id, count(*) from listing_wide&lt;br /&gt;group by vendor_id;&lt;br /&gt;&lt;br /&gt;select vendor_id, count(*) from listing_purge&lt;br /&gt;group by vendor_id;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Code&lt;br /&gt;----&lt;br /&gt;CREATE OR REPLACE procedure tmp_benchmark&lt;br /&gt;as&lt;br /&gt;l_cnt number := 0; l_upd_rows number := 0;&lt;br /&gt;l_fetch_limit PLS_INTEGER := 1000;&lt;br /&gt;&lt;br /&gt;cursor c2 is&lt;br /&gt;select listing_id, vendor_id, price, qty,hash_lite, hash_code, vendor_listing_id, author, title,subject,isbn_raw, bsa_vend, match_col&lt;br /&gt;from listing_purge partition (v2);&lt;br /&gt;&lt;br /&gt;TYPE listing_purge_tab is table of c2%rowtype;&lt;br /&gt;lt_book listing_purge_tab;&lt;br /&gt;&lt;br /&gt;BEGIN&lt;br /&gt;&lt;br /&gt;runStats_pkg.rs_start;&lt;br /&gt;&lt;br /&gt;INSERT INTO listing_wide&lt;br /&gt;(listing_id, vendor_id, price, qty,hash_lite, hash_code, vendor_listing_id, author, title,subject,isbn_raw, bsa_vend, match_col)&lt;br /&gt;select listing_id, vendor_id, price, qty,hash_lite, hash_code, vendor_listing_id, author, title,subject,isbn_raw, bsa_vend, match_col&lt;br /&gt;from listing_purge partition (v1);&lt;br /&gt;&lt;br /&gt;commit;&lt;br /&gt;&lt;br /&gt;runStats_pkg.rs_middle;&lt;br /&gt;&lt;br /&gt;-- Open cursor &lt;br /&gt;OPEN c2;&lt;br /&gt;&lt;br /&gt;LOOP&lt;br /&gt;fetch c2 BULK COLLECT INTO lt_book LIMIT l_fetch_limit;&lt;br /&gt;&lt;br /&gt;FORALL j IN lt_book.FIRST..lt_book.LAST&lt;br /&gt;INSERT into listing_wide&lt;br /&gt;(listing_id, vendor_id, price, qty,hash_lite, hash_code, vendor_listing_id, author, title,subject,isbn_raw, bsa_vend, match_col)&lt;br /&gt;values (lt_book(j).listing_id, lt_book(j).vendor_id, lt_book(j).price, lt_book(j).qty, lt_book(j).hash_lite, lt_book(j).hash_code, &lt;br /&gt;lt_book(j).vendor_listing_id, lt_book(j).author, lt_book(j).title, lt_book(j).subject, lt_book(j).isbn_raw, lt_book(j).bsa_vend&lt;br /&gt;, lt_book(j).match_col)&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;l_upd_rows := l_upd_rows + SQL%RowCount;&lt;br /&gt;&lt;br /&gt;exit when lt_book.COUNT &amp;lt; l_fetch_limit;&lt;br /&gt;--exit when c2%notfound;&lt;br /&gt;&lt;br /&gt;END LOOP;&lt;br /&gt;close c2;&lt;br /&gt;&lt;br /&gt;commit;&lt;br /&gt;&lt;br /&gt;runStats_pkg.rs_stop;&lt;br /&gt;&lt;br /&gt;EXCEPTION&lt;br /&gt;WHEN others THEN&lt;br /&gt;--u$err.err;&lt;br /&gt;raise;&lt;br /&gt;END;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;RunStats&lt;br /&gt;--------&lt;br /&gt;Run1 ran in 669 hsecs&lt;br /&gt;Run2 ran in 914 hsecs&lt;br /&gt;run 1 ran in 73.19% of the time&lt;br /&gt;&lt;br /&gt;Name                                  Run1        Run2        Diff&lt;br /&gt;STAT...parse count (hard)                2           3           1&lt;br /&gt;LATCH.DML lock allocation              328         327          -1&lt;br /&gt;STAT...sorts (memory)                    1           0          -1&lt;br /&gt;STAT...parse time cpu                    2           0          -2&lt;br /&gt;LATCH.internal temp table obje           4           2          -2&lt;br /&gt;LATCH.shared pool simulator              6           8           2&lt;br /&gt;LATCH.ASM db client latch                4           6           2&lt;br /&gt;STAT...enqueue releases              1,222       1,224           2&lt;br /&gt;LATCH.space background task la           7           5          -2&lt;br /&gt;STAT...redo log space requests           0           2           2&lt;br /&gt;STAT...Heap Segment Array Upda         146         148           2&lt;br /&gt;STAT...Heap Segment Array Inse          12          14           2&lt;br /&gt;STAT...HSC Heap Segment Block       50,222      50,224           2&lt;br /&gt;STAT...index scans kdiixs1              98          96          -2&lt;br /&gt;STAT...enqueue requests              1,220       1,224           4&lt;br /&gt;STAT...application wait time             0           4           4&lt;br /&gt;STAT...physical read total mul         153         148          -5&lt;br /&gt;STAT...redo ordering marks           1,121       1,126           5&lt;br /&gt;STAT...messages sent                    97         105           8&lt;br /&gt;STAT...session logical reads       147,017     147,029          12&lt;br /&gt;STAT...commit cleanouts              3,364       3,376          12&lt;br /&gt;STAT...consistent changes               24          38          14&lt;br /&gt;STAT...db block changes            154,297     154,313          16&lt;br /&gt;LATCH.Consistent RBA                    96          80         -16&lt;br /&gt;STAT...parse time elapsed               67          51         -16&lt;br /&gt;LATCH.lgwr LWN SCN                      97          78         -19&lt;br /&gt;STAT...redo entries                102,505     102,524          19&lt;br /&gt;STAT...redo buffer allocation            0          22          22&lt;br /&gt;LATCH.post/wait queue                    1          31          30&lt;br /&gt;STAT...recursive cpu usage              91         121          30&lt;br /&gt;STAT...redo log space wait tim           0          30          30&lt;br /&gt;STAT...CPU used by this sessio          91         125          34&lt;br /&gt;LATCH.session allocation             7,536       7,574          38&lt;br /&gt;LATCH.In memory undo latch               9          48          39&lt;br /&gt;STAT...physical read total IO          275         235         -40&lt;br /&gt;LATCH.row cache objects              2,688       2,642         -46&lt;br /&gt;STAT...execute count                   261         310          49&lt;br /&gt;STAT...consistent gets              19,683      19,632         -51&lt;br /&gt;LATCH.shared pool                      138         196          58&lt;br /&gt;STAT...db block gets               127,334     127,397          63&lt;br /&gt;LATCH.undo global data               8,608       8,537         -71&lt;br /&gt;STAT...active txn count during       8,180       8,107         -73&lt;br /&gt;STAT...recursive calls               3,858       3,941          83&lt;br /&gt;LATCH.enqueues                       2,034       2,132          98&lt;br /&gt;STAT...user I/O wait time              564         670         106&lt;br /&gt;LATCH.enqueue hash chains            2,525       2,634         109&lt;br /&gt;STAT...table scan rows gotten       50,445      50,315        -130&lt;br /&gt;LATCH.MinActiveScn Latch            16,931      16,796        -135&lt;br /&gt;LATCH.redo allocation                  295         467         172&lt;br /&gt;STAT...physical reads               10,010      10,194         184&lt;br /&gt;STAT...Number of read IOs issu           0         184         184&lt;br /&gt;LATCH.cache table scan latch           231          19        -212&lt;br /&gt;STAT...Elapsed Time                    669         920         251&lt;br /&gt;STAT...undo change vector size   3,185,292   3,185,592         300&lt;br /&gt;LATCH.redo writing                     295         709         414&lt;br /&gt;LATCH.multiblock read objects          464          38        -426&lt;br /&gt;LATCH.object queue header heap           3         451         448&lt;br /&gt;LATCH.active checkpoint queue            2         457         455&lt;br /&gt;LATCH.messages                         368       1,250         882&lt;br /&gt;LATCH.cache buffer handles          15,010      13,714      -1,296&lt;br /&gt;STAT...free buffer inspected        10,054      11,522       1,468&lt;br /&gt;LATCH.cache buffers lru chain       20,881      22,578       1,697&lt;br /&gt;LATCH.simulator hash latch          13,132      10,817      -2,315&lt;br /&gt;STAT...hot buffers moved to he         560       3,105       2,545&lt;br /&gt;STAT...IMU Redo allocation siz       8,236      11,044       2,808&lt;br /&gt;STAT...dirty buffers inspected           1       4,860       4,859&lt;br /&gt;LATCH.checkpoint queue latch           201       7,974       7,773&lt;br /&gt;LATCH.cache buffers chains         545,026     536,670      -8,356&lt;br /&gt;LATCH.object queue header oper      34,953      44,292       9,339&lt;br /&gt;STAT...physical reads cache pr       9,735         133      -9,602&lt;br /&gt;STAT...free buffer requested        20,720      10,987      -9,733&lt;br /&gt;STAT...consistent gets from ca      10,729         959      -9,770&lt;br /&gt;STAT...physical reads cache         10,010         184      -9,826&lt;br /&gt;STAT...physical reads direct             0      10,010      10,010&lt;br /&gt;STAT...consistent gets direct            0      10,010      10,010&lt;br /&gt;STAT...consistent gets from ca      19,683       9,622     -10,061&lt;br /&gt;STAT...redo size                78,097,020  78,123,668      26,648&lt;br /&gt;STAT...IMU undo allocation siz      52,228         908     -51,320&lt;br /&gt;STAT...physical read total byt  82,001,920  83,509,248   1,507,328&lt;br /&gt;STAT...physical IO disk bytes   82,001,920  83,509,248   1,507,328&lt;br /&gt;STAT...cell physical IO interc  82,001,920  83,509,248   1,507,328&lt;br /&gt;STAT...physical read bytes      82,001,920  83,509,248   1,507,328&lt;br /&gt;STAT...session pga memory                0   2,162,688   2,162,688&lt;br /&gt;STAT...Effective IO time                 0   6,195,022   6,195,022&lt;br /&gt;&lt;br /&gt;Run1 latches total versus runs -- difference and pct&lt;br /&gt;Run1        Run2        Diff       Pct&lt;br /&gt;672,749     681,506       8,757     98.72%&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-5675856919052490369?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/5675856919052490369/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=5675856919052490369' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/5675856919052490369'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/5675856919052490369'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/06/single-insert-vs-array-bulk-insert.html' title='single INSERT vs array BULK INSERT'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-1902675822689125803</id><published>2009-04-15T09:50:00.000-07:00</published><updated>2011-08-13T20:59:32.413-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='set based process'/><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>Benchmark row-by-row and set based process</title><content type='html'>Goal&lt;br /&gt;----&lt;br /&gt;Compare the performance benchmark for row-by-row update and single SQL set based update.&lt;br /&gt;The benchmark matrix supply supported information to Product Manager to prove why we should move some&lt;br /&gt;row-by-row "real time"(that can be near real time) processes to Asynchronous set based bulk process.&lt;br /&gt;&lt;br /&gt;file://T:/NextAction/benchmark_update_listing.sql&lt;br /&gt;&lt;br /&gt;Solution&lt;br /&gt;--------&lt;br /&gt;Generate testing data, update some rows, benchmark with RunStats package.&lt;br /&gt;&lt;br /&gt;Result&lt;br /&gt;------&lt;br /&gt;From benchmark, you can see &lt;br /&gt;&lt;br /&gt;- Set based process vs. row-by-row process, commit out the loop.&lt;br /&gt;Row-by-row process takes 3 times longer Elapsed Time, 3 times more CPU, 3 times more logical I/O,&lt;br /&gt;and use 258% more Latches, latches are a type of lock, locks are serialization devices, &lt;br /&gt;serialization devices inhibit scalability.&lt;br /&gt;&lt;br /&gt;- Set based process vs. row-by-row process, commit in the loop.&lt;br /&gt;Row-by-row process takes 5 times longer Elapsed Time, 5 times more CPU, 5 times more logical I/O,&lt;br /&gt;and use 1,019.26% more Latches.&lt;br /&gt;&lt;br /&gt;- If we introduce blocking row-by-row process from OIMS, by introducing more latches from different concurrent users,&lt;br /&gt;it will be even worse.&lt;br /&gt;A latch is a serialization device, the more people that request the same latch at the some time necessarily implies&lt;br /&gt;"longer runtimes" - as the number of concurrent users go up, so will the observed run times and cpu times &lt;br /&gt;(as you spin on the latch trying to get it), as we experience contention.&lt;br /&gt;&lt;br /&gt;So,&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;SQL SET BASED &lt;is better="" than=""&gt; BULK PROCESSING &lt;is better="" than=""&gt; SLOW BY SLOW&lt;br /&gt;&lt;br /&gt;You did good by turning slow by slow into BULK.&lt;br /&gt;&lt;br /&gt;You could have done better by turning BULK into SET OPERATION. &lt;/is&gt;&lt;/is&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Stats&lt;br /&gt;-----&lt;br /&gt;&lt;pre&gt;*) commit out the loop&lt;br /&gt;&lt;br /&gt;Run1 ran in 79 hsecs&lt;br /&gt;Run2 ran in 25 hsecs&lt;br /&gt;run 1 ran in 316% of the time&lt;br /&gt;&lt;br /&gt;Name                                              Run1          Run2          Diff&lt;br /&gt;STAT...db block changes                          4,555         4,568            13&lt;br /&gt;STAT...db block gets                             2,418         2,444            26&lt;br /&gt;STAT...Elapsed Time                                 80            26           -54&lt;br /&gt;STAT...CPU used by this session                     81            26           -55&lt;br /&gt;LATCH.simulator hash latch                         308           181          -127&lt;br /&gt;STAT...table scan rows gotten                    2,728         2,222          -506&lt;br /&gt;STAT...redo size                             5,841,592     5,842,304           712&lt;br /&gt;LATCH.checkpoint queue latch                     2,223           102        -2,121&lt;br /&gt;STAT...execute count                             2,224             4        -2,220&lt;br /&gt;STAT...sorts (memory)                            2,222             0        -2,222&lt;br /&gt;LATCH.MinActiveScn Latch                         2,428           198        -2,230&lt;br /&gt;LATCH.object queue header operation              2,862           393        -2,469&lt;br /&gt;STAT...undo change vector size               2,837,256     2,839,872         2,616&lt;br /&gt;LATCH.cache buffers lru chain                    4,445           195        -4,250&lt;br /&gt;STAT...session logical reads                     9,292         2,751        -6,541&lt;br /&gt;STAT...consistent gets                           6,874           307        -6,567&lt;br /&gt;LATCH.cache buffers chains                      23,525        12,415       -11,110&lt;br /&gt;&lt;br /&gt;Run1 latches total versus runs -- difference and pct&lt;br /&gt;Run1          Run2          Diff        Pct&lt;br /&gt;36,466        14,118       -22,348    258.29%&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;*) commit in the loop&lt;br /&gt;&lt;br /&gt;Run1 ran in 129 hsecs&lt;br /&gt;Run2 ran in 24 hsecs&lt;br /&gt;run 1 ran in 537.5% of the time&lt;br /&gt;&lt;br /&gt;Name                                              Run1          Run2          Diff&lt;br /&gt;STAT...CPU used by this session                    130            26          -104&lt;br /&gt;STAT...Elapsed Time                                132            25          -107&lt;br /&gt;LATCH.Consistent RBA                             1,260             8        -1,252&lt;br /&gt;STAT...commit cleanouts                          2,224           100        -2,124&lt;br /&gt;LATCH.redo writing                               3,782            25        -3,757&lt;br /&gt;LATCH.cache buffers lru chain                    4,454           195        -4,259&lt;br /&gt;STAT...db block changes                          8,916         4,572        -4,344&lt;br /&gt;LATCH.session allocation                         4,481            52        -4,429&lt;br /&gt;STAT...db block gets                             8,917         2,456        -6,461&lt;br /&gt;STAT...consistent gets                           6,882           408        -6,474&lt;br /&gt;STAT...recursive calls                           6,714            35        -6,679&lt;br /&gt;LATCH.redo allocation                            8,225            29        -8,196&lt;br /&gt;LATCH.In memory undo latch                       8,893            11        -8,882&lt;br /&gt;LATCH.DML lock allocation                        8,891             7        -8,884&lt;br /&gt;LATCH.undo global data                          11,136           129       -11,007&lt;br /&gt;STAT...session logical reads                    15,799         2,864       -12,935&lt;br /&gt;LATCH.enqueue hash chains                       13,351            25       -13,326&lt;br /&gt;LATCH.cache buffers chains                      60,632        12,552       -48,080&lt;br /&gt;STAT...undo change vector size               2,989,432     2,841,148      -148,284&lt;br /&gt;STAT...redo size                             6,391,412     5,844,136      -547,276&lt;br /&gt;STAT...IMU undo allocation size              4,193,320         1,080    -4,192,240&lt;br /&gt;&lt;br /&gt;Run1 latches total versus runs -- difference and pct&lt;br /&gt;Run1          Run2          Diff        Pct&lt;br /&gt;145,815        14,306      -131,509  1,019.26%&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Setup&lt;br /&gt;-----&lt;br /&gt;&lt;br /&gt;drop table listing_wide purge;&lt;br /&gt;create table listing_wide&lt;br /&gt;(&lt;br /&gt;vendor_id   number(10,0)  Not Null ,&lt;br /&gt;listing_id   number(20,0)  Not Null ,&lt;br /&gt;vendor_listing_id  Varchar(40)  Not Null ,&lt;br /&gt;hash_code  VarChar2(32)  Not Null  ,&lt;br /&gt;qty   number(5,0)  Not Null  ,&lt;br /&gt;price  number(10,2) Not Null  ,&lt;br /&gt;currency  varchar2(3) default 'USD' Not Null,&lt;br /&gt;listingtype  number(4,0) default 1001  Not Null,&lt;br /&gt;book_lang varchar2(3) default ' ' Not Null ,&lt;br /&gt;create_date Date default sysdate Not Null ,&lt;br /&gt;update_date Date default sysdate Not Null ,&lt;br /&gt;abe_cat0 varchar2(100)     ,&lt;br /&gt;abe_cat1  varchar2(100)      ,&lt;br /&gt;abe_cat2  varchar2(100)      ,&lt;br /&gt;vend_bsa  Varchar2(30)     ,&lt;br /&gt;abe_bsa  Varchar2(30)     ,&lt;br /&gt;binding  varchar2(30)    ,&lt;br /&gt;booktype varchar2(30)     ,&lt;br /&gt;bookcondition varchar2(30)     ,&lt;br /&gt;cat_providerid Number(5,0)    ,&lt;br /&gt;cat_providerkey Varchar2(50)    ,&lt;br /&gt;edition_num  number(10)      ,&lt;br /&gt;edition_txt  varchar2(40)      ,&lt;br /&gt;editor  varchar(255)    ,&lt;br /&gt;illustrator varchar2(255)    ,&lt;br /&gt;inscription varchar2(50)    ,&lt;br /&gt;isbn_raw  Varchar2(25)             ,&lt;br /&gt;isbn_vendor13 Number(13,0)     ,&lt;br /&gt;isbn_matched13 Number(13,0)     ,&lt;br /&gt;jacketcondition Varchar2(30)    ,&lt;br /&gt;pictures Varchar2(255)    ,&lt;br /&gt;printing  Varchar2(20)      ,&lt;br /&gt;publisher_name  varchar2(750)      ,&lt;br /&gt;publisher_year  Number(4)      ,&lt;br /&gt;publisher_location  varchar2(750)     ,&lt;br /&gt;item_size   Varchar2(50)     ,&lt;br /&gt;subject  Varchar2(2000)     ,&lt;br /&gt;synopsis Varchar2(255)    ,&lt;br /&gt;author   varchar(750)      ,&lt;br /&gt;title  varchar2(750)    ,&lt;br /&gt;vend_cat varchar2(255)    ,&lt;br /&gt;volume  Varchar2(50)    ,&lt;br /&gt;weight  Varchar2(40)    ,&lt;br /&gt;description varchar2(4000)&lt;br /&gt;--, constraint listing_wide_pk primary key(listing_id)&lt;br /&gt;)&lt;br /&gt;-- TABLESPACE data_auto&lt;br /&gt;NOLOGGING&lt;br /&gt;PARTITION BY LIST (vendor_id) &lt;br /&gt;(  &lt;br /&gt;PARTITION v2134736  values( 2134736 ),&lt;br /&gt;PARTITION v8408184  values( 8408184 ),&lt;br /&gt;PARTITION v999  values( 999 ),&lt;br /&gt;PARTITION vendor_NULL  VALUES (NULL),&lt;br /&gt;PARTITION vendor_small VALUES (DEFAULT)&lt;br /&gt;)&lt;br /&gt;NOCOMPRESS &lt;br /&gt;NOPARALLEL&lt;br /&gt;ENABLE ROW MOVEMENT;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;create index listing_wide_i_hs on listing_wide(vendor_listing_id, hash_code) local nologging;&lt;br /&gt;create index listing_wide_i_id on listing_wide(listing_id) local nologging;&lt;br /&gt;&lt;br /&gt;truncate table listing_wide;&lt;br /&gt;&lt;br /&gt;insert /*+ append */ into listing_wide &lt;br /&gt;(listing_id, vendor_id, price, qty, hash_code, vendor_listing_id, author, title,description,isbn_raw, vend_bsa)&lt;br /&gt;select&lt;br /&gt;rownum listing_id, &lt;br /&gt;mod(rownum,8) vendor_id,&lt;br /&gt;10.55 price,&lt;br /&gt;30 qty,&lt;br /&gt;rpad('x',31,'x') hash_code,&lt;br /&gt;rownum vendor_listing_id,&lt;br /&gt;rpad(rownum,400,'x') author,&lt;br /&gt;rpad('x',400,'x') title,&lt;br /&gt;rpad('x',300,'x') description,&lt;br /&gt;rownum isbn_raw,&lt;br /&gt;mod(rownum,100)||','||mod(Round(rownum/10),100) bsa&lt;br /&gt;from dual&lt;br /&gt;connect by level &amp;lt;= 100100;&lt;br /&gt;&lt;br /&gt;commit;&lt;br /&gt;&lt;br /&gt;select vendor_id, isbn_raw, hash_code, author&lt;br /&gt;from listing_wide where rownum &amp;lt;= 3;&lt;br /&gt;&lt;br /&gt;exec dbms_stats.gather_table_stats(user,'listing_wide');&lt;br /&gt;&lt;br /&gt;drop table listing_file;&lt;br /&gt;&lt;br /&gt;create table listing_file&lt;br /&gt;PARTITION BY LIST (time_part_key)&lt;br /&gt;SUBPARTITION BY LIST (match_col)&lt;br /&gt;SUBPARTITION TEMPLATE &lt;br /&gt;(SUBPARTITION vendor_id_part  VALUES (1) ,&lt;br /&gt;SUBPARTITION hash_code_part  VALUES (2) ,&lt;br /&gt;SUBPARTITION listing_id_part VALUES (3) ,&lt;br /&gt;SUBPARTITION other_part VALUES (DEFAULT)&lt;br /&gt;)&lt;br /&gt;(&lt;br /&gt;PARTITION data_part_0 VALUES (0),&lt;br /&gt;PARTITION data_part_1 VALUES (1),&lt;br /&gt;PARTITION data_part_2 VALUES (2),&lt;br /&gt;PARTITION data_part_3 VALUES (3),&lt;br /&gt;PARTITION data_part_4 VALUES (4),&lt;br /&gt;PARTITION data_part_5 VALUES (5),&lt;br /&gt;--PARTITION dummy_null  VALUES (NULL),&lt;br /&gt;PARTITION dummy_other VALUES (DEFAULT)&lt;br /&gt;)&lt;br /&gt;--tablespace data_auto&lt;br /&gt;nologging&lt;br /&gt;as&lt;br /&gt;select a.* &lt;br /&gt;--, cast(null as timestamp(3)) update_date&lt;br /&gt;, cast(null as number(2))    time_part_key&lt;br /&gt;, 9 dest_queue&lt;br /&gt;, 9 match_col&lt;br /&gt;from listing_wide a&lt;br /&gt;where 1=0;&lt;br /&gt;&lt;br /&gt;alter table listing_file modify (&lt;br /&gt;currency  varchar2(3) default 'USD' ,&lt;br /&gt;listingtype  number(4,0) default 1001  ,&lt;br /&gt;book_lang varchar2(3) default ' '  ,&lt;br /&gt;create_date Date default sysdate  ,&lt;br /&gt;update_date Date default sysdate &lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;alter table listing_file modify&lt;br /&gt;(&lt;br /&gt;update_date    default systimestamp,&lt;br /&gt;time_part_key  default mod(floor(to_number(to_char(sysdate,'mi'))/10),10)&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;truncate table listing_file;&lt;br /&gt;&lt;br /&gt;insert /*+ append */ into listing_file&lt;br /&gt;(listing_id, vendor_id, price, qty, hash_code, vendor_listing_id, author, title,description,isbn_raw, vend_bsa&lt;br /&gt;, match_col)&lt;br /&gt;select&lt;br /&gt;rownum listing_id, &lt;br /&gt;mod(rownum,8) vendor_id,&lt;br /&gt;10.55 price,&lt;br /&gt;30 qty,&lt;br /&gt;rpad('x',31,'x') hash_code,&lt;br /&gt;rownum vendor_listing_id,&lt;br /&gt;rpad(rownum,400,'x') author,&lt;br /&gt;rpad('x',400,'x') title,&lt;br /&gt;rpad('x',300,'x') description,&lt;br /&gt;rownum isbn_raw,&lt;br /&gt;mod(rownum,100)||','||mod(Round(rownum/10),100) bsa,&lt;br /&gt;3 match_col&lt;br /&gt;from dual&lt;br /&gt;connect by level &amp;lt;= 2222;&lt;br /&gt;&lt;br /&gt;commit;&lt;br /&gt;&lt;br /&gt;exec dbms_stats.gather_table_stats(user,'listing_file');&lt;br /&gt;&lt;br /&gt;Test&lt;br /&gt;----&lt;br /&gt;&lt;br /&gt;set linesize 120&lt;br /&gt;set serveroutput on&lt;br /&gt;&lt;br /&gt;Begin&lt;br /&gt;runstats_pkg.rs_start;&lt;br /&gt;&lt;br /&gt;for s in (select * from listing_file)&lt;br /&gt;loop&lt;br /&gt;update  listing_wide d&lt;br /&gt;set&lt;br /&gt;d.price      = s.price    ,&lt;br /&gt;d.qty       = s.qty    ,&lt;br /&gt;d.hash_code      = s.hash_code   ,&lt;br /&gt;d.vendor_listing_id = s.vendor_listing_id,&lt;br /&gt;d.author      = s.author    ,&lt;br /&gt;d.title      = s.title   ,&lt;br /&gt;d.description     = s.description  ,&lt;br /&gt;d.isbn_raw      = s.isbn_raw   ,&lt;br /&gt;d.vend_bsa     = s.vend_bsa   &lt;br /&gt;where s.vendor_id = d.vendor_id and s.listing_id = d.listing_id&lt;br /&gt;;&lt;br /&gt;--commit;&lt;br /&gt;&lt;br /&gt;end loop;&lt;br /&gt;commit;&lt;br /&gt;&lt;br /&gt;runstats_pkg.rs_middle;&lt;br /&gt;&lt;br /&gt;MERGE INTO listing_wide d&lt;br /&gt;using listing_file s&lt;br /&gt;on (s.vendor_id = d.vendor_id and s.listing_id = d.listing_id)&lt;br /&gt;when matched then&lt;br /&gt;update set&lt;br /&gt;d.price      = s.price    ,&lt;br /&gt;d.qty       = s.qty    ,&lt;br /&gt;d.hash_code      = s.hash_code   ,&lt;br /&gt;d.vendor_listing_id = s.vendor_listing_id,&lt;br /&gt;d.author      = s.author    ,&lt;br /&gt;d.title      = s.title   ,&lt;br /&gt;d.description     = s.description  ,&lt;br /&gt;d.isbn_raw      = s.isbn_raw   ,&lt;br /&gt;d.vend_bsa     = s.vend_bsa   &lt;br /&gt;;&lt;br /&gt;commit;&lt;br /&gt;&lt;br /&gt;runstats_pkg.rs_stop(5);&lt;br /&gt;End;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Reference&lt;br /&gt;---------&lt;br /&gt;&lt;a href="http://tkyte.blogspot.com/2006/10/slow-by-slow.html"&gt;http://tkyte.blogspot.com/2006/10/slow-by-slow.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, sans-serif; font-size: 12px; line-height: 16px;"&gt;&lt;em style="list-style-image: initial; list-style-position: initial; list-style-type: none; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;bulking&lt;/em&gt;&amp;nbsp;it up with BULK COLLECT,&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, sans-serif; font-size: 12px; line-height: 16px;"&gt;&amp;nbsp;bulk-update them back into the database, using the FORALL statement with the UPDATE&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;a href="http://www.oracle.com/technetwork/issue-archive/2011/11-may/o31asktom-354139.html"&gt;http://www.oracle.com/technetwork/issue-archive/2011/11-may/o31asktom-354139.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-1902675822689125803?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/1902675822689125803/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=1902675822689125803' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/1902675822689125803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/1902675822689125803'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/04/benchmark-row-by-row-and-set-based.html' title='Benchmark row-by-row and set based process'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-1795886513242759745</id><published>2009-04-14T10:17:00.000-07:00</published><updated>2009-04-14T19:36:30.865-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CBO'/><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>table stats tool script</title><content type='html'>Since I saw Ningoo show his dandy tool tbsql and made my mouth watering, and he was reluctant to share his favorite tool, so I have to create one myself.&lt;br /&gt;The good news is he promised he will open source it in someday.&lt;br /&gt;&lt;br /&gt;Purpose:&lt;br /&gt;Display table and its index statistics by specify Owner and Table_Name.&lt;br /&gt;It can help you investigate the SQL query optimizer issue, cooperate with 10053 trace tool. And it can do more...&lt;br /&gt;&lt;br /&gt;Reference:&lt;br /&gt;&lt;a href="http://www.ningoo.net/html/2009/how_to_get_extent_id_from_rowid.html"&gt;http://www.ningoo.net/html/2009/how_to_get_extent_id_from_rowid.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here is the script:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/*&lt;br /&gt;&lt;br /&gt;-- File name:   table.sql&lt;br /&gt;-- Goal: display table and index statistics by specify Owner and Table_Name&lt;br /&gt;--&lt;br /&gt;-- Author: Yi (Charlie) Zhu&lt;br /&gt;-- update: 29-Jan-2009&lt;br /&gt;-- Blog:   http://mujiang.blogspot.com/&lt;br /&gt;--              &lt;br /&gt;-- Usage:       @table [owner] [table_name]&lt;br /&gt;&lt;br /&gt;29-Jan-2009: Charlie: Show popular value chart for height balance histogram&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Reference&lt;br /&gt;--&lt;br /&gt;http://www.ningoo.net/html/2009/how_to_get_extent_id_from_rowid.html&lt;br /&gt;&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;define owner='&amp;1'&lt;br /&gt;define table_name='&amp;2'&lt;br /&gt;&lt;br /&gt;set serveroutput off&lt;br /&gt;set timing off&lt;br /&gt;set verify off&lt;br /&gt;set linesize 200&lt;br /&gt;set define &amp;&lt;br /&gt;&lt;br /&gt;COLUMN SEGMENT_NAME FORMAT A40 HEADING 'Segment Name'&lt;br /&gt;COLUMN SEGMENT_TYPE FORMAT A25 HEADING 'Segment Type'&lt;br /&gt;COLUMN SEGMENT_SUBTYPE FORMAT A25 HEADING 'Segment SubType'&lt;br /&gt;COLUMN Tablespace_Name FORMAT A30 HEADING 'Tablespace_Name'&lt;br /&gt;COLUMN Partition_NAME FORMAT A25 HEADING 'Partition Name'&lt;br /&gt;COLUMN subpartition_name FORMAT A22 HEADING 'SubPartition Name'&lt;br /&gt;COLUMN INDEX_NAME FORMAT A30 HEADING 'INDEX Name'&lt;br /&gt;COLUMN COLUMN_NAME FORMAT A30 HEADING 'COLUMN NAME'&lt;br /&gt;COLUMN DATA_TYPE FORMAT A14 HEADING 'DATA TYPE'&lt;br /&gt;COLUMN LOW_VALUE FORMAT A14 HEADING 'LOW_VALUE'&lt;br /&gt;COLUMN HIGH_VALUE FORMAT A14 HEADING 'HIGH_VALUE'&lt;br /&gt;COLUMN owner FORMAT A14&lt;br /&gt;COLUMN table_name FORMAT A30&lt;br /&gt;COLUMN HISTOGRAM FORMAT A9&lt;br /&gt;COLUMN endpoint_actual_value format A30&lt;br /&gt;&lt;br /&gt;COLUMN BLOCKS FORMAT 999,999,999 HEADING 'Blocks'&lt;br /&gt;COLUMN MBytes FORMAT 999,999,999 HEADING 'MBytes'&lt;br /&gt;COLUMN TOTAL_BYTES FORMAT 999,999 HEADING 'TotByte_MB'&lt;br /&gt;COLUMN extents FORMAT 999,999&lt;br /&gt;COLUMN LAST_ANALYZED FORMAT A11 HEADING 'LAST|ANALYZED'&lt;br /&gt;COLUMN pop_chart FORMAT A11 HEADING 'Pop Chart'&lt;br /&gt;&lt;br /&gt;COLUMN unf         FORMAT 999,999.99 HEADING 'unf_K'&lt;br /&gt;COLUMN fs1         FORMAT 999,999.99 HEADING 'fs1_K'&lt;br /&gt;COLUMN fs2         FORMAT 999,999.99 HEADING 'fs2_K'&lt;br /&gt;COLUMN fs3         FORMAT 999,999.99 HEADING 'fs3_K'&lt;br /&gt;COLUMN fs4         FORMAT 999,999.99 HEADING 'fs4_K'&lt;br /&gt;COLUMN full        FORMAT 999,999.99 HEADING 'full_K'&lt;br /&gt;COLUMN total_blocks    FORMAT 999,999.99 HEADING 'total_blocks_K'&lt;br /&gt;COLUMN unused_blocks   FORMAT 999,999.99 HEADING 'unused_blocks_K'&lt;br /&gt;COLUMN unfb        FORMAT 999,999 HEADING 'unfb_M'&lt;br /&gt;COLUMN fs1b        FORMAT 999,999 HEADING 'fs1b_M'&lt;br /&gt;COLUMN fs2b        FORMAT 999,999 HEADING 'fs2b_M'&lt;br /&gt;COLUMN fs3b        FORMAT 999,999 HEADING 'fs3b_M'&lt;br /&gt;COLUMN fs4b        FORMAT 999,999 HEADING 'fs4b_M'&lt;br /&gt;COLUMN fullb        FORMAT 999,999 HEADING 'fullb_M'&lt;br /&gt;COLUMN total_bytes     FORMAT 999,999 HEADING 'total_bytes_M'&lt;br /&gt;COLUMN unused_bytes    FORMAT 999,999 HEADING 'unused_bytes_M'&lt;br /&gt;COLUMN last_extf       FORMAT 999,999 HEADING 'last_extf_id'&lt;br /&gt;COLUMN last_extb       FORMAT 9999999999 HEADING 'last_extb_id'&lt;br /&gt;COLUMN lastusedblock/1024   FORMAT 9999999999 HEADING 'lastusedblock'&lt;br /&gt;&lt;br /&gt;col num_rows new_value l_num_rows;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;spool table_info.log&lt;br /&gt;&lt;br /&gt;prompt table info&lt;br /&gt;&lt;br /&gt;SELECT owner,table_name,pct_free,num_rows,blocks,chain_cnt,&lt;br /&gt;avg_row_len,to_char(last_analyzed,'yyyy-mon-dd') last_analyzed,buffer_pool&lt;br /&gt;FROM dba_tables&lt;br /&gt;WHERE owner = (Upper('&amp;&amp;owner'))&lt;br /&gt;and table_name IN (Upper('&amp;&amp;table_name'))&lt;br /&gt;ORDER BY blocks desc;&lt;br /&gt;&lt;br /&gt;prompt table stats&lt;br /&gt;&lt;br /&gt;SELECT partition_name,subpartition_name,num_rows, blocks, empty_blocks, avg_space, chain_cnt, avg_row_len&lt;br /&gt;FROM dba_tab_statistics&lt;br /&gt;WHERE owner = (Upper('&amp;&amp;owner'))&lt;br /&gt;and table_name IN (Upper('&amp;&amp;table_name'))&lt;br /&gt;order by table_name,partition_position;&lt;br /&gt;&lt;br /&gt;-- IOT come with Primary Key index name&lt;br /&gt;select owner||'.'||segment_name segment_name,partition_name,round(bytes/1024/1024) mbytes,&lt;br /&gt; blocks,extents,segment_type,tablespace_name&lt;br /&gt;from dba_segments&lt;br /&gt;WHERE owner = (Upper('&amp;&amp;owner'))&lt;br /&gt;and segment_name IN (Upper('&amp;&amp;table_name'))&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;prompt column data type&lt;br /&gt;&lt;br /&gt;SELECT --OWNER,TABLE_NAME,COLUMN_ID,&lt;br /&gt; COLUMN_NAME,DATA_TYPE,DATA_LENGTH,DATA_PRECISION&lt;br /&gt;FROM dba_tab_cols&lt;br /&gt;WHERE owner = (Upper('&amp;&amp;owner'))&lt;br /&gt;and TABLE_NAME IN (Upper('&amp;&amp;table_name'))&lt;br /&gt;order by owner,table_name,column_name&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;prompt column stats&lt;br /&gt;&lt;br /&gt;SELECT&lt;br /&gt; column_name AS "NAME",&lt;br /&gt; num_distinct AS "#DST",&lt;br /&gt; low_value,&lt;br /&gt; high_value,&lt;br /&gt; density AS "DENS",&lt;br /&gt; num_nulls AS "#NULL",&lt;br /&gt; avg_col_len AS "AVGLEN",&lt;br /&gt; histogram,&lt;br /&gt; num_buckets AS "#BKT"&lt;br /&gt;FROM dba_tab_col_statistics&lt;br /&gt;WHERE owner = (Upper('&amp;&amp;owner'))&lt;br /&gt;  and TABLE_NAME IN (Upper('&amp;&amp;table_name'))&lt;br /&gt;order by column_name&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;prompt column frequency histogram&lt;br /&gt;&lt;br /&gt;SELECT column_name, endpoint_value, endpoint_actual_value, endpoint_number,&lt;br /&gt; endpoint_number - lag(endpoint_number,1,0) OVER (partition by column_name ORDER BY endpoint_number) AS frequency&lt;br /&gt;FROM dba_tab_histograms&lt;br /&gt;WHERE owner = (Upper('&amp;&amp;owner'))&lt;br /&gt;and table_name = (Upper('&amp;&amp;table_name'))&lt;br /&gt;and column_name in &lt;br /&gt;(select column_name FROM dba_tab_col_statistics &lt;br /&gt; where owner = (Upper('&amp;&amp;owner'))&lt;br /&gt; and TABLE_NAME IN (Upper('&amp;&amp;table_name'))&lt;br /&gt; and histogram = 'FREQUENCY'&lt;br /&gt;)&lt;br /&gt;ORDER BY column_name, endpoint_number;&lt;br /&gt;&lt;br /&gt;prompt column height-balanced histogram&lt;br /&gt;&lt;br /&gt;SELECT column_name, endpoint_value, endpoint_number&lt;br /&gt;, Max(endpoint_number) OVER (partition by column_name) Max_EPN&lt;br /&gt;, endpoint_number - lag(endpoint_number,1,0) OVER (partition by column_name ORDER BY endpoint_number) AS popular_count&lt;br /&gt;, &amp;l_num_rows * (endpoint_number - lag(endpoint_number,1,0) OVER (partition by column_name ORDER BY endpoint_number))&lt;br /&gt;  /(Max(endpoint_number) OVER (partition by column_name))  AS Est_Card&lt;br /&gt;, rpad('.',endpoint_number - lag(endpoint_number,1,0) OVER (partition by column_name ORDER BY endpoint_number) - 1,'x') pop_chart&lt;br /&gt;FROM dba_tab_histograms&lt;br /&gt;WHERE owner = (Upper('&amp;&amp;owner'))&lt;br /&gt;and table_name = (Upper('&amp;&amp;table_name'))&lt;br /&gt;and column_name in &lt;br /&gt;(select column_name FROM dba_tab_col_statistics &lt;br /&gt; where owner = (Upper('&amp;&amp;owner'))&lt;br /&gt; and TABLE_NAME IN (Upper('&amp;&amp;table_name'))&lt;br /&gt; and histogram = 'HEIGHT BALANCED'&lt;br /&gt;)&lt;br /&gt;ORDER BY column_name, endpoint_number;&lt;br /&gt;&lt;br /&gt;prompt Index name,physical size,including columns and selectivity&lt;br /&gt;&lt;br /&gt;SELECT m.INDEX_NAME,COLUMN_NAME,&lt;br /&gt; COLUMN_POSITION,DISTINCT_KEYS,LEAF_BLOCKS,NUM_ROWS, COLUMN_LENGTH&lt;br /&gt;FROM DBA_INDEXES m,dba_ind_columns d&lt;br /&gt;WHERE m.owner = (Upper('&amp;&amp;owner'))&lt;br /&gt;AND m.INDEX_NAME = d.INDEX_NAME&lt;br /&gt;AND m.OWNER = d.TABLE_OWNER&lt;br /&gt;AND m.TABLE_NAME = d.TABLE_NAME&lt;br /&gt;AND m.TABLE_NAME IN (Upper('&amp;&amp;table_name'))&lt;br /&gt;ORDER BY index_name,column_position;&lt;br /&gt;&lt;br /&gt;prompt index stats&lt;br /&gt;&lt;br /&gt;SELECT&lt;br /&gt; index_name,&lt;br /&gt; blevel,&lt;br /&gt; leaf_blocks AS leaf_blks,&lt;br /&gt; distinct_keys AS dst_keys,&lt;br /&gt; num_rows,&lt;br /&gt; clustering_factor AS clust_fact,&lt;br /&gt; avg_leaf_blocks_per_key AS leaf_per_key,&lt;br /&gt; avg_data_blocks_per_key AS data_per_key&lt;br /&gt;FROM dba_ind_statistics&lt;br /&gt;WHERE owner = (Upper('&amp;&amp;owner'))&lt;br /&gt;AND TABLE_OWNER = (Upper('&amp;&amp;owner'))&lt;br /&gt;AND TABLE_NAME IN (Upper('&amp;&amp;table_name'));&lt;br /&gt;&lt;br /&gt;VARIABLE total_blocks NUMBER&lt;br /&gt;VARIABLE total_bytes NUMBER&lt;br /&gt;VARIABLE unused_blocks NUMBER&lt;br /&gt;VARIABLE unused_bytes NUMBER&lt;br /&gt;VARIABLE last_extf NUMBER&lt;br /&gt;VARIABLE last_extb NUMBER&lt;br /&gt;VARIABLE lastusedblock NUMBER&lt;br /&gt;begin&lt;br /&gt; DBMS_SPACE.UNUSED_SPACE(Upper('&amp;&amp;owner'), Upper('&amp;&amp;table_name'), 'TABLE',:total_blocks,&lt;br /&gt;    :total_bytes,:unused_blocks,:unused_bytes,:last_extf,&lt;br /&gt;    :last_extb,:lastusedblock);&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;select &lt;br /&gt;:total_bytes  /1024/1024 total_bytes  ,&lt;br /&gt;:unused_bytes /1024/1024 unused_bytes ,&lt;br /&gt;:total_blocks /1024 total_blocks ,&lt;br /&gt;:unused_blocks/1024 unused_blocks,&lt;br /&gt;:lastusedblock/1024 lastusedblock     ,&lt;br /&gt;:last_extf          last_extf     ,&lt;br /&gt;:last_extb          last_extb&lt;br /&gt;from dual;&lt;br /&gt;&lt;br /&gt;variable unf number; &lt;br /&gt;variable unfb number; &lt;br /&gt;variable fs1 number; &lt;br /&gt;variable fs1b number; &lt;br /&gt;variable fs2 number; &lt;br /&gt;variable fs2b number; &lt;br /&gt;variable fs3 number; &lt;br /&gt;variable fs3b number; &lt;br /&gt;variable fs4 number; &lt;br /&gt;variable fs4b number; &lt;br /&gt;variable full number; &lt;br /&gt;variable fullb number; &lt;br /&gt;&lt;br /&gt;-- shows the space usage of data blocks under the segment High Water Mark&lt;br /&gt;&lt;br /&gt;begin &lt;br /&gt;dbms_space.space_usage(Upper('&amp;&amp;owner'),Upper('&amp;&amp;table_name'),&lt;br /&gt;                        'TABLE', &lt;br /&gt;                        :unf,:unfb,&lt;br /&gt;                        :fs1,:fs1b,&lt;br /&gt;                        :fs2,:fs2b,&lt;br /&gt;                        :fs3,:fs3b,&lt;br /&gt;                        :fs4,:fs4b,&lt;br /&gt;                        :full,:fullb);&lt;br /&gt;end; &lt;br /&gt;/ &lt;br /&gt;&lt;br /&gt;select &lt;br /&gt; :unf /1024 unf&lt;br /&gt;,:fs1 /1024 fs1&lt;br /&gt;,:fs2 /1024 fs2&lt;br /&gt;,:fs3 /1024 fs3&lt;br /&gt;,:fs4 /1024 fs4&lt;br /&gt;,:full /1024 full&lt;br /&gt;,:unfb /1024/1024 unfb&lt;br /&gt;,:fs1b /1024/1024 fs1b&lt;br /&gt;,:fs2b /1024/1024 fs2b&lt;br /&gt;,:fs3b /1024/1024 fs3b&lt;br /&gt;,:fs4b /1024/1024 fs4b&lt;br /&gt;,:fullb /1024/1024 fullb&lt;br /&gt;from dual;&lt;br /&gt;&lt;br /&gt;spool off&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;-- unf: unformatted_blocks&lt;br /&gt;&lt;br /&gt;print unf ; &lt;br /&gt;print unfb ; &lt;br /&gt;print fs4 ; &lt;br /&gt;print fs4b; &lt;br /&gt;print fs3 ; &lt;br /&gt;print fs3b; &lt;br /&gt;print fs2 ; &lt;br /&gt;print fs2b; &lt;br /&gt;print fs1 ; &lt;br /&gt;print fs1b; &lt;br /&gt;print full; &lt;br /&gt;print fullb; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- Returns the list of segments that are associated with the object&lt;br /&gt;select * from Table(&lt;br /&gt;DBMS_SPACE.OBJECT_DEPENDENT_SEGMENTS(&lt;br /&gt;   objowner =&gt; Upper('&amp;&amp;owner'),&lt;br /&gt;   objname  =&gt; Upper('&amp;&amp;table_name'),&lt;br /&gt;   partname =&gt; Null,&lt;br /&gt;   objtype  =&gt; 1)&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;SQL&gt; print&lt;br /&gt;&lt;br /&gt;TOTAL_BLOCKS  TOTAL_BYTES UNUSED_BLOCKS UNUSED_BYTES   LASTEXTF  LAST_EXTB LASTUSEDBLOCK&lt;br /&gt;------------  ----------- ------------- ------------ ---------- ---------- -------------&lt;br /&gt;        1536     12582912             0            0          5       1545           128&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;       UNF       UNFB&lt;br /&gt;---------- ----------&lt;br /&gt;         0          0&lt;br /&gt;&lt;br /&gt;FreeSpace1: 0 to 25% free space&lt;br /&gt;FreeSpace2: 25 to 50% free space&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;       FS1        FS2        FS3        FS4       FULL&lt;br /&gt;---------- ---------- ---------- ---------- ----------&lt;br /&gt;       386         25         16        945        132&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      FS1B       FS2B       FS3B        FS4B      FULLB&lt;br /&gt;---------- ---------- ----------  ---------- ----------&lt;br /&gt;   3162112     204800     131072     7741440    1081344&lt;br /&gt;&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-1795886513242759745?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/1795886513242759745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=1795886513242759745' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/1795886513242759745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/1795886513242759745'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/04/table-stats-tool-script.html' title='table stats tool script'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-2566148419211889686</id><published>2009-04-08T10:51:00.000-07:00</published><updated>2009-04-08T11:01:18.438-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='work'/><category scheme='http://www.blogger.com/atom/ns#' term='instrument'/><title type='text'>debug.f to instrument PL/SQL code</title><content type='html'>Purpose&lt;br /&gt;-------&lt;br /&gt;Code Instrumentation is the fine art of making every other line of code be debug.&lt;br /&gt;Here we show you how to install and implement debug.f in you PL/SQL code.&lt;br /&gt;&lt;br /&gt;Download&lt;br /&gt;--------&lt;br /&gt;debugf:  db.zip contains the code, then extract and save all files to a local folder.&lt;br /&gt;&lt;a href="http://asktom.oracle.com/~tkyte/debugf"&gt;http://asktom.oracle.com/~tkyte/debugf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Discussion&lt;br /&gt;----------&lt;br /&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:10445025326812"&gt;"Instrumentation overhead"&lt;/a&gt;&lt;br /&gt;http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:10445025326812&lt;br /&gt;&lt;br /&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:51960184066540"&gt;"The 10 (Oracle Development) Commandments"&lt;/a&gt;&lt;br /&gt;http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:51960184066540&lt;br /&gt;&lt;br /&gt;Setup&lt;br /&gt;-----&lt;br /&gt;suggest you &lt;br /&gt;&lt;br /&gt;create a utility user:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create user utility identified by utility;&lt;br /&gt;grant create session, create procedure, create table, create trigger to utility;&lt;br /&gt;alter user utility default tablespace users quota unlimited on users;&lt;br /&gt;&lt;br /&gt;connect sys as sysdba&lt;br /&gt;grant execute on utl_file to utility;&lt;br /&gt;grant create public synonym, create any DIRECTORY to utility;&lt;br /&gt;&lt;br /&gt;run install_debug in that schema &lt;br /&gt;create a public synonym for debug &lt;br /&gt;And then you can use it. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;connect utility/utility&lt;br /&gt;@install_debug.sql&lt;br /&gt;--@A:\plsql\debugf\install_debug.sql&lt;br /&gt;&lt;br /&gt;create public synonym debug for utility.debug;&lt;br /&gt;grant execute on utility.debug to public;&lt;br /&gt;&lt;br /&gt;DROP DIRECTORY debug_dir;&lt;br /&gt;CREATE or replace DIRECTORY debug_dir AS '/data1/debug';&lt;br /&gt;CREATE or replace DIRECTORY debug_dir AS '/u01/debug';&lt;br /&gt;&lt;br /&gt;CREATE or replace DIRECTORY debug_dir AS 'c:/temp/log';&lt;br /&gt;&lt;br /&gt;--GRANT READ, WRITE ON DIRECTORY debug_dir TO PUBLIC; &lt;br /&gt;--exec debug.clear;&lt;br /&gt;--exec debug.init(p_file=&gt;'DEBUG_DIR/system.dbg');&lt;br /&gt;&lt;br /&gt;-- Enable debug trace for current login user&lt;br /&gt;declare&lt;br /&gt;  ls_user varchar2(30) DEFAULT USER;&lt;br /&gt;begin&lt;br /&gt; debug.clear;&lt;br /&gt; debug.init(p_file=&gt;'DEBUG_DIR/'||ls_user||'.dbg');&lt;br /&gt; debug.status;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- Set module name to trace, p_modules=&gt;'&lt;package_name OR stand alone procedure_name&gt;'&lt;br /&gt;-- Enable trace for a user, p_user=&gt;'SYSTEM'&lt;br /&gt;declare&lt;br /&gt; ls_trace_user varchar2(30) := 'CS_USER';&lt;br /&gt;BEGIN&lt;br /&gt; debug.clear(p_user=&gt;ls_trace_user);&lt;br /&gt; debug.init(p_modules=&gt;'ALL', p_user=&gt;ls_trace_user,&lt;br /&gt;   --p_date_format=&gt;'YYYY/MM/DD HH24:MI:SS',&lt;br /&gt;   p_show_sesid=&gt;'YES',&lt;br /&gt;   p_file=&gt;'DEBUG_DIR/'||ls_trace_user||'.dbg');&lt;br /&gt; debug.status(p_user=&gt;ls_trace_user);&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;-- batch setup logging users&lt;br /&gt;declare&lt;br /&gt; ls_trace_user ct_type;&lt;br /&gt;BEGIN&lt;br /&gt;&lt;br /&gt; ls_trace_user := ct_type ('SYS','SYSTEM','ABEDBA','ABELISTING');&lt;br /&gt;&lt;br /&gt; FOR i IN ls_trace_user.FIRST .. ls_trace_user.LAST&lt;br /&gt; LOOP&lt;br /&gt;  debug.clear(p_user=&gt;ls_trace_user(i));&lt;br /&gt;  debug.init(p_modules=&gt;'ALL', p_user=&gt;ls_trace_user(i),&lt;br /&gt;    --p_date_format=&gt;'YYYY/MM/DD HH24:MI:SS',&lt;br /&gt;    p_show_sesid=&gt;'NO',&lt;br /&gt;    p_file=&gt;'DEBUG_DIR/'||ls_trace_user(i)||'.dbg');&lt;br /&gt;  debug.status(p_user=&gt;ls_trace_user(i));&lt;br /&gt; End Loop;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;Demo 1&lt;br /&gt;------&lt;br /&gt;&lt;br /&gt;Begin&lt;br /&gt;  debug.f('start %s : %s', 1, sysdate);&lt;br /&gt;  debug.f(SubStr(TO_CHAR(SQLCODE)||': '||SQLERRM,1,100));&lt;br /&gt;Exception&lt;br /&gt;    WHEN OTHERS THEN&lt;br /&gt;      debug.f(SubStr(TO_CHAR(SQLCODE)||': '||SQLERRM,1,100));&lt;br /&gt;End;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;Demo 2&lt;br /&gt;------&lt;br /&gt;&lt;br /&gt;@connect "/ as sysdba"&lt;br /&gt;grant execute on dbms_lock to ops$tkyte;&lt;br /&gt;@connect /&lt;br /&gt;&lt;br /&gt;set echo on&lt;br /&gt;/*&lt;br /&gt;first we'll start by enabling debug - this would be done once, sets up a &lt;br /&gt;table with values...&lt;br /&gt;&lt;br /&gt;After that, we'll watch the debug....&lt;br /&gt;*/&lt;br /&gt;exec debug.init&lt;br /&gt;exec debug.f( 'hello world' );&lt;br /&gt;pause&lt;br /&gt;set define off&lt;br /&gt;host xterm -e tail -f /tmp/OPS\$TKYTE.dbg &amp;&lt;br /&gt;set define on&lt;br /&gt;&lt;br /&gt;create or replace procedure want_to_trace&lt;br /&gt;as&lt;br /&gt;begin&lt;br /&gt;    for i in 1 .. 10&lt;br /&gt;    loop&lt;br /&gt;        if ( mod(i,2) = 0 )&lt;br /&gt;        then&lt;br /&gt;            debug.f( 'processing step %s of 10 - %s', i , 'odd');&lt;br /&gt;            dbms_lock.sleep(1);&lt;br /&gt;        else&lt;br /&gt;            debug.f( 'processing step %s of 10', i );&lt;br /&gt;            dbms_lock.sleep(1);&lt;br /&gt;        end if;&lt;br /&gt;    end loop;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;exec want_to_trace&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;monitor&lt;br /&gt;-------&lt;br /&gt;&lt;code&gt;&lt;br /&gt;To trace it:&lt;br /&gt;tail -f [DEBUG_DIR]/[LOGIN USER].dbg&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;For example:&lt;br /&gt;tail -f /data1/debug/SYSTEM.dbg&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-2566148419211889686?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/2566148419211889686/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=2566148419211889686' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/2566148419211889686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/2566148419211889686'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/04/debugf-to-instrument-plsql-code.html' title='debug.f to instrument PL/SQL code'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-4180030136973013659</id><published>2009-04-07T14:39:00.000-07:00</published><updated>2009-04-07T14:42:16.068-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CBO'/><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>New efficient HASH FULL OUTER join in 11g</title><content type='html'>Purpose:&lt;br /&gt;--&lt;br /&gt;Oracle 11g query optimizer introduced a new HASH JOIN FULL OUTER execution method.&lt;br /&gt;&lt;br /&gt;Starting with Oracle Database 11g Release 1 (11.1), Oracle Database automatically uses a native execution method based on a hash join for executing full outer joins whenever possible. When the new method is used to execute a full outer join, the execution plan for the query contains HASH JOIN FULL OUTER.&lt;br /&gt;&lt;br /&gt;To instruct the optimizer not to consider using the hash full outer join execution method, apply the NO_NATIVE_FULL_OUTER_JOIN hint. The NO_NATIVE_FULL_OUTER_JOIN hint instructs the optimizer to exclude the native execution method when joining each specified table. Instead, the full outer join is executed as a union of left outer join and an anti-join.&lt;br /&gt;&lt;br /&gt;Result&lt;br /&gt;--&lt;br /&gt;The new HASH JOIN FULL OUTER execution method logical reads(Buffers in execution plan output) cost equals too two base table FULL scan logical I/O adds up, nothing more.&lt;br /&gt;The old full outer join cost 4 times more LIO on table scan.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Benchmark&lt;br /&gt;---------&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;drop table t1 purge;&lt;br /&gt;drop table t2 purge;&lt;br /&gt;&lt;br /&gt;create table t1&lt;br /&gt;as&lt;br /&gt;select&lt;br /&gt; rownum + 5 id,&lt;br /&gt; rpad('x',500,'x') c1&lt;br /&gt;from dual&lt;br /&gt;connect by level &lt;= 5000;&lt;br /&gt;&lt;br /&gt;create table t2&lt;br /&gt;as&lt;br /&gt;select&lt;br /&gt; rownum + 15 id,&lt;br /&gt; rpad('x',500,'x') c1&lt;br /&gt;from dual&lt;br /&gt;connect by level &lt;= 5000;&lt;br /&gt;&lt;br /&gt;set serveroutput off&lt;br /&gt;set linesize 170&lt;br /&gt;set pagesize 0&lt;br /&gt;&lt;br /&gt;select max(t1c1), max(t2c1)&lt;br /&gt;from (&lt;br /&gt;select /*+ gather_plan_statistics */ t1.id, t2.id, t1.c1 t1c1, t2.c1 t2c1&lt;br /&gt;from t1 full outer join t2&lt;br /&gt;on t1.id = t2.id&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;-- 10g way&lt;br /&gt;SELECT * FROM table(dbms_xplan.display_cursor(NULL,NULL, 'runstats_last'));&lt;br /&gt;&lt;br /&gt;-- 11g way&lt;br /&gt;SELECT * FROM table(dbms_xplan.display_cursor(NULL,NULL, 'iostats memstats last partition'));&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation               | Name | A-Rows | Buffers | Reads  | Writes| A-Time     |&lt;br /&gt;-----------------------------------------------------------------------------------------&lt;br /&gt;|   1 | SORT AGGREGATE          |      |      1 |     732 |    101 |     0 |00:00:00.15 |&lt;br /&gt;|   2 |  VIEW                   |      |   5010 |     732 |    101 |     0 |00:00:00.06 |&lt;br /&gt;|   3 |   UNION-ALL             |      |   5010 |     732 |    101 |     0 |00:00:00.05 |&lt;br /&gt;|*  4 |    HASH JOIN RIGHT OUTER|      |   5000 |     366 |    101 |     0 |00:00:00.04 |&lt;br /&gt;|   5 |     TABLE ACCESS FULL   | T2   |   5000 |     183 |     56 |     0 |00:00:00.01 |&lt;br /&gt;|   6 |     TABLE ACCESS FULL   | T1   |   5000 |     183 |     45 |     0 |00:00:00.01 |&lt;br /&gt;|*  7 |    HASH JOIN RIGHT ANTI |      |     10 |     366 |      0 |     0 |00:00:00.01 |&lt;br /&gt;|   8 |     TABLE ACCESS FULL   | T1   |   5000 |     183 |      0 |     0 |00:00:00.01 |&lt;br /&gt;|   9 |     TABLE ACCESS FULL   | T2   |   5000 |     183 |      0 |     0 |00:00:00.01 |&lt;br /&gt;-----------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;------------------------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation              | Name     | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |&lt;br /&gt;------------------------------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT       |          |      1 |00:00:00.09 |     184 |       |       |          |&lt;br /&gt;|   1 |  SORT AGGREGATE        |          |      1 |00:00:00.09 |     184 |       |       |          |&lt;br /&gt;|   2 |   VIEW                 | VW_FOJ_0 |   5010 |00:00:00.03 |     184 |       |       |          |&lt;br /&gt;|*  3 |    HASH JOIN FULL OUTER|          |   5010 |00:00:00.03 |     184 |  3239K|  1058K| 3539K (0)|&lt;br /&gt;|   4 |     TABLE ACCESS FULL  | T2       |   5000 |00:00:00.01 |      92 |       |       |          |&lt;br /&gt;|   5 |     TABLE ACCESS FULL  | T1       |   5000 |00:00:00.01 |      92 |       |       |          |&lt;br /&gt;------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Reference&lt;br /&gt;--&lt;br /&gt;Oracle® Database Performance Tuning Guide 11g Release 1 (11.1)&lt;br /&gt; - 11 The Query Optimizer, 11.6.7 Outer Joins&lt;br /&gt;OracleQueryOptimizer11g_20081202.pdf by Christian Antognini&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-4180030136973013659?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/4180030136973013659/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=4180030136973013659' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/4180030136973013659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/4180030136973013659'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/04/new-efficient-hash-full-outer-join-in.html' title='New efficient HASH FULL OUTER join in 11g'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-8796398208198434073</id><published>2009-04-01T10:32:00.000-07:00</published><updated>2009-04-01T10:36:59.689-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='work'/><title type='text'>PL/SQL instrument utility u$err package</title><content type='html'>Purpose&lt;br /&gt;-------&lt;br /&gt;1. PL/SQL utility to Instrument and Trace.&lt;br /&gt;2. Err_Trap.&lt;br /&gt;&lt;br /&gt;debug.f() write to db server trace file&lt;br /&gt;u$err.trc() write to utility.error_log table, with autonomous transaction.&lt;br /&gt;&lt;br /&gt;u$err.err() write error stack to utility.error_log table, and DBMS_OUTPUT to std_io.&lt;br /&gt;&lt;br /&gt;File: file://A:/PLSQL/debugf/u$err_pkg.sql&lt;br /&gt;&lt;br /&gt;Setup&lt;br /&gt;-----&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;drop table utility.error_log;&lt;br /&gt;create table utility.error_log&lt;br /&gt;(err_code varchar2(10), err_module varchar2(30), err_action varchar2(30), &lt;br /&gt; create_date date default SYSDATE, create_user varchar2(30) default USER,&lt;br /&gt; err_text varchar2(4000)&lt;br /&gt;)&lt;br /&gt;partition by range (create_date) INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))&lt;br /&gt;(&lt;br /&gt; PARTITION p0 VALUES LESS THAN (TO_DATE('1-1-2009', 'DD-MM-YYYY'))&lt;br /&gt;)&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;grant select on utility.error_log to qa_admin;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Code&lt;br /&gt;----&lt;br /&gt;&lt;br /&gt;CREATE OR REPLACE PACKAGE utility.u$err AS&lt;br /&gt;&lt;br /&gt;/***&lt;br /&gt;DEFUG.F : log trace information&lt;br /&gt;***/&lt;br /&gt;&lt;br /&gt; PROCEDURE trc (p_msg IN VARCHAR2);&lt;br /&gt;&lt;br /&gt; PROCEDURE err (p_msg IN VARCHAR2 default '');&lt;br /&gt;&lt;br /&gt;END;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;CREATE OR REPLACE PACKAGE BODY utility.u$err AS&lt;br /&gt;&lt;br /&gt;/***&lt;br /&gt;Goal: 1. Trace, 2. Err_Trap&lt;br /&gt;&lt;br /&gt;Who| Date         | What&lt;br /&gt;Charlie(Yi 木匠) | 12-June-2008 | combine FORMAT_ERROR_BACKTRACE and DBMS_UTILITY.FORMAT_ERROR_STACK to one string&lt;br /&gt;&lt;br /&gt;DEFUG.F&lt;br /&gt;&lt;br /&gt;set serveroutput on size 200000&lt;br /&gt;&lt;br /&gt;alter package utility.u$err compile;&lt;br /&gt;grant execute on utility.u$err to public;&lt;br /&gt;create or replace public synonym u$err for utility.u$err;&lt;br /&gt;&lt;br /&gt;File: A:\PLSQL\debugf\u$err_pkg.sql&lt;br /&gt;&lt;br /&gt;***/&lt;br /&gt;&lt;br /&gt; PROCEDURE trc (p_msg IN VARCHAR2)&lt;br /&gt; IS&lt;br /&gt;   PRAGMA AUTONOMOUS_TRANSACTION;&lt;br /&gt;   ls_module varchar2(32767);&lt;br /&gt;   ls_action varchar2(32767);&lt;br /&gt;   ls_code varchar2(10);&lt;br /&gt; BEGIN&lt;br /&gt;   DBMS_APPLICATION_INFO.READ_MODULE ( &lt;br /&gt;    module_name =&gt; ls_module, &lt;br /&gt;    action_name =&gt; ls_action); &lt;br /&gt;   ls_code := to_char(sqlcode);&lt;br /&gt;&lt;br /&gt;   INSERT INTO error_log (err_code,err_module,err_action,err_text)&lt;br /&gt;                  VALUES(ls_code,substr(ls_module,1,30),substr(ls_action,1,30), p_msg);&lt;br /&gt;   COMMIT;&lt;br /&gt;   DBMS_OUTPUT.PUT_LINE('trc:'||ls_code||':'||ls_action||':'||ls_module||':'||p_msg);&lt;br /&gt; EXCEPTION&lt;br /&gt;   WHEN OTHERS THEN&lt;br /&gt;     ROLLBACK;&lt;br /&gt;     DBMS_OUTPUT.PUT_LINE('Error in log_err: '||SUBSTR(SQLERRM,1,120));&lt;br /&gt; END;&lt;br /&gt;&lt;br /&gt; PROCEDURE err (p_msg IN VARCHAR2)&lt;br /&gt; IS&lt;br /&gt;  ls_err varchar2(32767);&lt;br /&gt; BEGIN&lt;br /&gt;   ls_err := SubStr(p_msg||'.'||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'&lt;---'||&lt;br /&gt;     chr(10)||DBMS_UTILITY.FORMAT_ERROR_STACK, 1, 2000);&lt;br /&gt;   debug.f(ls_err);&lt;br /&gt;   u$err.trc (ls_err);&lt;br /&gt;   DBMS_APPLICATION_INFO.SET_MODULE(Null, Null);&lt;br /&gt; EXCEPTION&lt;br /&gt;   WHEN OTHERS THEN&lt;br /&gt;     u$err.trc (SubStr(DBMS_UTILITY.FORMAT_ERROR_STACK,1,500));&lt;br /&gt;     DBMS_OUTPUT.PUT_LINE('Error stack in log_err: '||SUBSTR(SQLERRM,1,120));&lt;br /&gt; END;&lt;br /&gt;&lt;br /&gt;END;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;alter package utility.u$err compile;&lt;br /&gt;grant execute on utility.u$err to public;&lt;br /&gt;create or replace public synonym u$err for utility.u$err;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Test u$err.err and u$err.trc&lt;br /&gt;----&lt;br /&gt;exec u$err.err;&lt;br /&gt;&lt;br /&gt;declare&lt;br /&gt; li pls_integer;&lt;br /&gt; procedure p_in&lt;br /&gt; is&lt;br /&gt; begin&lt;br /&gt;   li := 5 / 0;&lt;br /&gt; exception&lt;br /&gt;  when others then&lt;br /&gt;   u$err.err;&lt;br /&gt;   raise;&lt;br /&gt; end;&lt;br /&gt; &lt;br /&gt;begin&lt;br /&gt; u$err.trc('start');&lt;br /&gt; p_in;&lt;br /&gt; u$err.trc('end');&lt;br /&gt;exception&lt;br /&gt; when others then&lt;br /&gt;  u$err.err('outer error');&lt;br /&gt;  u$err.trc('before raise');&lt;br /&gt;  raise;&lt;br /&gt;  u$err.trc('after raise');&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;-- Query data&lt;br /&gt;select * from &lt;br /&gt;(&lt;br /&gt;select * from utility.error_log&lt;br /&gt; -- PARTITION FOR(to_date('11-mar-2009','dd-mon-yyyy'))&lt;br /&gt;order by create_date desc&lt;br /&gt;) where rownum &lt; 10;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Housekeeping&lt;br /&gt;----&lt;br /&gt;--Purge old log&lt;br /&gt;delete utility.error_log where create_date &lt; sysdate - 100;&lt;br /&gt;commit;&lt;br /&gt;&lt;br /&gt;ALTER TABLE utility.error_log DROP PARTITION FOR(to_date('11-mar-2009','dd-mon-yyyy'));&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Reference&lt;br /&gt;---------&lt;br /&gt;&lt;a href="http://www.oreilly.com/catalog/9780596514105"&gt;Oracle PL/SQL Best Practices&lt;/a&gt; - Steven Feuerstein&lt;br /&gt;http://www.oreilly.com/catalog/9780596514105&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-8796398208198434073?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/8796398208198434073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=8796398208198434073' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/8796398208198434073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/8796398208198434073'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/04/plsql-instrument-utility-uerr-package.html' title='PL/SQL instrument utility u$err package'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-462451034003198335</id><published>2009-03-13T09:47:00.000-07:00</published><updated>2009-03-15T21:05:00.799-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><title type='text'>How to display SQL code in text format exactly</title><content type='html'>In a blog post, we often need to display the program code, e.g. PL/SQL, SQL, and pure text output and trace file contents in text format exactly as it is, including space.&lt;br /&gt;&lt;br /&gt;It had been bothering me for a long time. Finally, I found the solution, to use &lt;span style="font-weight: bold;"&gt;&lt; pre &gt; and &lt; /pre &gt;&lt;/span&gt; HTML tags.&lt;br /&gt;&lt;br /&gt;Here is an example for RunStats output:&lt;br /&gt;(Tested on http://www.blogger.com)&lt;br /&gt;&lt;br /&gt;Without format:&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;..............................Fixed-Length...Delimited........Diff&lt;br /&gt;STAT...CPU used by this sessio         179         202          23  ***&lt;br /&gt;STAT...Elapsed Time                    179          91         -88  ***&lt;br /&gt;STAT...DB time                           0         421         421  xxx&lt;br /&gt;LATCH.process queue reference            1      58,878      58,877  ***&lt;br /&gt;STAT...physical read bytes         212,992           0    -212,992&lt;br /&gt;STAT...session uga memory max      604,728     115,320    -489,408&lt;br /&gt;STAT...session pga memory max      720,896     131,072    -589,824&lt;br /&gt;&lt;br /&gt;Run1 latches total versus runs -- difference and pct&lt;br /&gt;Run1        Run2        Diff       Pct&lt;br /&gt;7,629      64,444      56,815     11.84%&lt;br /&gt;&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;With &lt; pre &gt; and &lt; /pre &gt; tags to format text:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;..............................Fixed-Length...Delimited........Diff&lt;br /&gt;STAT...CPU used by this sessio         179         202          23  ***&lt;br /&gt;STAT...Elapsed Time                    179          91         -88  ***&lt;br /&gt;STAT...DB time                           0         421         421  xxx&lt;br /&gt;LATCH.process queue reference            1      58,878      58,877  ***&lt;br /&gt;STAT...physical read bytes         212,992           0    -212,992&lt;br /&gt;STAT...session uga memory max      604,728     115,320    -489,408&lt;br /&gt;STAT...session pga memory max      720,896     131,072    -589,824&lt;br /&gt;&lt;br /&gt;Run1 latches total versus runs -- difference and pct&lt;br /&gt;Run1        Run2        Diff       Pct&lt;br /&gt;7,629      64,444      56,815     11.84%&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;span&gt;I learned something new today, I'm so happy.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Reference&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.echoecho.com/htmltext04.htm"&gt;http://www.echoecho.com/htmltext04.htm&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-462451034003198335?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/462451034003198335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=462451034003198335' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/462451034003198335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/462451034003198335'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/03/how-to-display-sql-code-in-text-format.html' title='How to display SQL code in text format exactly'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-7619709397111153289</id><published>2009-02-12T16:38:00.000-08:00</published><updated>2009-03-31T10:50:29.084-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hint'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>NO_INDEX hint and deprecated ROWID hint</title><content type='html'>Scope&lt;br /&gt;-----&lt;br /&gt;Many people asked how to specify ROWID hint for a SQL statement after Oracle 10g, and there is no answer by search Google.&lt;br /&gt;The RowID access path is helpful when you do iterative update(query the rows, do some changes, and then update back).&lt;br /&gt;&lt;br /&gt;Goal&lt;br /&gt;----&lt;br /&gt;Guide SQL access TABLE BY ROWID where there is a possible index access path.&lt;br /&gt;&lt;br /&gt;Solution&lt;br /&gt;--------&lt;br /&gt;&lt;br /&gt;*) approach 1: NO_INDEX sql hint&lt;br /&gt;*) approach 2: Suppress index scan by add expression/function to predicate column.&lt;br /&gt;&lt;br /&gt;Result&lt;br /&gt;------&lt;br /&gt;After benchmark, we can see that SQL optimizer and SQL run time engine select the "TABLE ACCESS BY USER ROWID" access path by implement the our solutions.&lt;br /&gt;The Logical reads(Buffers in the execution plan) reduced from 2 to 1.&lt;br /&gt;&lt;br /&gt;Setup&lt;br /&gt;-----&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;drop table yi01;&lt;br /&gt;create table yi01&lt;br /&gt;(myid number,&lt;br /&gt;mycol varchar2(30),&lt;br /&gt;constraint yi01_pk primary key(myid) using index&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;truncate table yi01;&lt;br /&gt;&lt;br /&gt;insert into yi01(myid, mycol) values(1, Null);&lt;br /&gt;insert into yi01(myid, mycol) values(2, Null);&lt;br /&gt;insert into yi01(myid, mycol) values(3, Null);&lt;br /&gt;insert into yi01(myid, mycol) values(4, 'a');&lt;br /&gt;insert into yi01(myid, mycol) values(5, Null);&lt;br /&gt;insert into yi01(myid, mycol) values(6, 'b');&lt;br /&gt;insert into yi01(myid, mycol) values(7, Null);&lt;br /&gt;&lt;br /&gt;insert into yi01(myid, mycol)&lt;br /&gt;select rownum + 7, Null&lt;br /&gt;from dual&lt;br /&gt;connect by level &lt;= 5010; &lt;br /&gt;&lt;br /&gt;commit;&lt;br /&gt;&lt;br /&gt;exec dbms_stats.gather_table_stats(user,'YI01');&lt;br /&gt;&lt;br /&gt;Benchmark&lt;br /&gt;--------- &lt;br /&gt;&lt;br /&gt;SQL&gt;&lt;br /&gt;&lt;br /&gt;set linesize 120&lt;br /&gt;set pagesize 0&lt;br /&gt;set serveroutput off&lt;br /&gt;&lt;br /&gt;COLUMN rid NEW_VALUE l_rid&lt;br /&gt;COLUMN myid NEW_VALUE l_id&lt;br /&gt;&lt;br /&gt;select rowid rid, myid from yi01&lt;br /&gt;where rownum &lt;= 1;  &lt;br /&gt;&lt;br /&gt;*) index range/unique scan&lt;br /&gt;&lt;br /&gt;update /*+ gather_plan_statistics index(a) */ YI01 a&lt;br /&gt;set MYCOL = 'F'&lt;br /&gt;WHERE rowid = '&amp;l_rid' and MYID = &amp;l_id;&lt;br /&gt;&lt;br /&gt;SELECT * FROM table(CAST (dbms_xplan.display_cursor(NULL,NULL, 'runstats_last') AS SYS.DBMS_XPLAN_TYPE_TABLE));&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------------&lt;br /&gt;| Id  | Operation         | Name    | E-Rows | A-Rows | Buffers |&lt;br /&gt;-----------------------------------------------------------------&lt;br /&gt;|   1 | UPDATE            |         |        |      1 |       2 |&lt;br /&gt;|*  2 |  INDEX UNIQUE SCAN| YI01_PK |      1 |      1 |       2 |&lt;br /&gt;-----------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;   2 - access("MYID"=1165)&lt;br /&gt;       filter(ROWID='AAAYH+AAEAAAAhoASM')&lt;br /&gt;&lt;br /&gt;*) approach 1: NO_INDEX sql hint&lt;br /&gt;&lt;br /&gt;update /*+ gather_plan_statistics no_index(a) */ YI01 a&lt;br /&gt;set MYCOL = 'F'&lt;br /&gt;WHERE rowid = 'AAA5znAG2AAAPm0AAF' and MYID = 7;&lt;br /&gt;&lt;br /&gt;SELECT * FROM table(CAST (dbms_xplan.display_cursor(NULL,NULL, 'runstats_last') AS SYS.DBMS_XPLAN_TYPE_TABLE));&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;-----------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                  | Name | E-Rows | A-Rows | Buffers |&lt;br /&gt;-----------------------------------------------------------------------&lt;br /&gt;|   1 | UPDATE                     |      |        |      1 |       1 |&lt;br /&gt;-----------------------------------------------------------------------&lt;br /&gt;|*  2 |  TABLE ACCESS BY USER ROWID| YI01 |      1 |      1 |       1 |&lt;br /&gt;-----------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;  2 - filter("MYID"=:SYS_B_2)&lt;br /&gt;&lt;br /&gt;rollback;&lt;br /&gt;&lt;br /&gt;*) approach 2: Surpress index scan by add expression/function to predicate column.&lt;br /&gt;&lt;br /&gt;update /*+ gather_plan_statistics */ YI01 a&lt;br /&gt;set MYCOL = 'F'&lt;br /&gt;WHERE rowid = '&amp;l_rid' and MYID + 0 = &amp;l_id;&lt;br /&gt;&lt;br /&gt;SELECT * FROM table(CAST (dbms_xplan.display_cursor(NULL,NULL, 'runstats_last') AS SYS.DBMS_XPLAN_TYPE_TABLE));&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                  | Name | E-Rows | A-Rows | Buffers |&lt;br /&gt;-----------------------------------------------------------------------&lt;br /&gt;|   1 | UPDATE                     |      |        |      1 |       1 |&lt;br /&gt;|*  2 |  TABLE ACCESS BY USER ROWID| YI01 |      1 |      1 |       1 |&lt;br /&gt;-----------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;  2 - filter("MYID"+0=1954)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Reference&lt;br /&gt;---------&lt;br /&gt;&lt;br /&gt;*) To get the current SQL execution plan in shared_pool.&lt;br /&gt;&lt;br /&gt;Oracle 11g&lt;br /&gt;SELECT * FROM table(dbms_xplan.display_cursor);&lt;br /&gt;&lt;br /&gt;Oracle 10.1&lt;br /&gt;SELECT * FROM table(CAST (dbms_xplan.display_cursor(NULL,NULL, 'runstats_last') AS SYS.DBMS_XPLAN_TYPE_TABLE));&lt;br /&gt;&lt;br /&gt;-- 10gR1&lt;br /&gt;SELECT * FROM table(dbms_xplan.display_cursor(NULL,NULL, 'runstats_last'));&lt;br /&gt;&lt;br /&gt;-- 11g&lt;br /&gt;SELECT * FROM table(dbms_xplan.display_cursor(NULL,NULL, 'iostats memstats last partition'));&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-7619709397111153289?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/7619709397111153289/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=7619709397111153289' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/7619709397111153289'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/7619709397111153289'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/02/noindex-hint-and-deprecated-rowid-hint.html' title='NO_INDEX hint and deprecated ROWID hint'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-6975898883825971318</id><published>2009-02-03T16:40:00.000-08:00</published><updated>2009-03-22T21:51:23.356-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='undo'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>update and undo</title><content type='html'>Goal&lt;br /&gt;----&lt;br /&gt;Research how to skip the update on some columns.&lt;br /&gt;Logically, Update table set column = column is an option.&lt;br /&gt;Need to check the resource usage.&lt;br /&gt;&lt;br /&gt;Result&lt;br /&gt;------&lt;br /&gt;Update column without change the value, still generate same amount of undo and redo.&lt;br /&gt;The undo is proportion to target value size.&lt;br /&gt;&lt;br /&gt;Tested on Oracle 11.1.0.7&lt;br /&gt;&lt;br /&gt;Setup&lt;br /&gt;-----&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;drop table t;&lt;br /&gt;drop table t1;&lt;br /&gt;&lt;br /&gt;create table t nologging&lt;br /&gt;as&lt;br /&gt;select rownum id, lpad('x',500,'x') c1&lt;br /&gt;from dual&lt;br /&gt;connect by level &lt;= 50000;&lt;br /&gt;&lt;br /&gt;create table t1 nologging&lt;br /&gt;as&lt;br /&gt;select rownum id, lpad('x',500,'x') c1&lt;br /&gt;from dual&lt;br /&gt;connect by level &lt;= 50000;&lt;br /&gt;&lt;br /&gt;set serveroutput on&lt;br /&gt;&lt;br /&gt;Benchmark&lt;br /&gt;---------&lt;br /&gt;exec runstats_pkg.rs_start;&lt;br /&gt;update t set id = id, c1 = c1;&lt;br /&gt;commit;&lt;br /&gt;exec runstats_pkg.rs_middle;&lt;br /&gt;update t1 set id = id;&lt;br /&gt;commit;&lt;br /&gt;exec runstats_pkg.rs_stop;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Run1 ran in 414 hsecs&lt;br /&gt;Run2 ran in 119 hsecs&lt;br /&gt;run 1 ran in 347.9% of the time&lt;br /&gt;&lt;br /&gt;Name                                  Run1        Run2        Diff&lt;br /&gt;LATCH.shared pool                      117         120           3&lt;br /&gt;STAT...redo synch time                  23           7         -16&lt;br /&gt;STAT...redo buffer allocation           16           0         -16&lt;br /&gt;LATCH.DML lock allocation               22           5         -17&lt;br /&gt;STAT...physical reads                1,786       1,808          22&lt;br /&gt;LATCH.redo writing                      62          22         -40&lt;br /&gt;LATCH.redo allocation                   78          23         -55&lt;br /&gt;STAT...CPU used by this sessio          73          16         -57&lt;br /&gt;LATCH.enqueues                         152          84         -68&lt;br /&gt;STAT...commit cleanouts                979       1,120         141&lt;br /&gt;STAT...rollback changes - undo         142           0        -142&lt;br /&gt;LATCH.cache buffers lru chain        4,909       5,184         275&lt;br /&gt;STAT...Elapsed Time                    414         119        -295&lt;br /&gt;STAT...DB time                         418         119        -299&lt;br /&gt;STAT...IMU Redo allocation siz       9,412      15,396       5,984&lt;br /&gt;STAT...consistent changes           48,013          30     -47,983&lt;br /&gt;STAT...consistent gets              51,861       1,878     -49,983&lt;br /&gt;STAT...redo entries                 54,046       3,579     -50,467&lt;br /&gt;STAT...db block gets                56,883       2,111     -54,772&lt;br /&gt;STAT...IMU undo allocation siz      63,992       1,080     -62,912&lt;br /&gt;STAT...db block changes            110,023       7,330    -102,693&lt;br /&gt;STAT...session logical reads       108,744       3,989    -104,755&lt;br /&gt;STAT...physical read bytes      29,261,824  29,622,272     360,448&lt;br /&gt;LATCH.cache buffers chains         487,509      26,861    -460,648&lt;br /&gt;STAT...undo change vector size  32,362,024   2,399,528 -29,962,496&lt;br /&gt;STAT...redo size                69,525,648   5,092,152 -64,433,496&lt;br /&gt;&lt;br /&gt;Run1 latches total versus runs -- difference and pct&lt;br /&gt;Run1        Run2        Diff       Pct&lt;br /&gt;521,401      45,711    -475,690  1,140.65%&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-6975898883825971318?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/6975898883825971318/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=6975898883825971318' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/6975898883825971318'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/6975898883825971318'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/02/update-and-undo.html' title='update and undo'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-4104596770423106125</id><published>2009-02-02T16:43:00.000-08:00</published><updated>2009-03-13T10:29:28.646-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='external table'/><category scheme='http://www.blogger.com/atom/ns#' term='work'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>External table benchmark fixed-length vs. delimited format</title><content type='html'>Goal&lt;br /&gt;----&lt;br /&gt;Compare the External Table read performance on Fix length format vs Tab(any char) Delimited format.&lt;br /&gt;&lt;br /&gt;Result&lt;br /&gt;------&lt;br /&gt;Fixed-length format flat file use up about 10% less CPU and 7 times less Latches resource than delimited format.&lt;br /&gt;But Delimited format took 50% less Elapsed Time in my test case.&lt;br /&gt;And one interesting point is that DB time for Fixed-length format is 0.&lt;br /&gt;&lt;br /&gt;Tested on Oracle 11.1.0.7&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;..............................Fixed-Length...Delimited........Diff&lt;br /&gt;STAT...CPU used by this sessio         179         202          23  ***&lt;br /&gt;STAT...Elapsed Time                    179          91         -88  ***&lt;br /&gt;STAT...DB time                           0         421         421  xxx&lt;br /&gt;LATCH.process queue reference            1      58,878      58,877  ***&lt;br /&gt;STAT...physical read bytes         212,992           0    -212,992&lt;br /&gt;STAT...session uga memory max      604,728     115,320    -489,408&lt;br /&gt;STAT...session pga memory max      720,896     131,072    -589,824&lt;br /&gt;&lt;br /&gt;Run1 latches total versus runs -- difference and pct&lt;br /&gt;Run1        Run2        Diff       Pct&lt;br /&gt;7,629      64,444      56,815     11.84%&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;# Fixed-length records are processed faster than records terminated by a string.&lt;br /&gt;# Fixed-length fields are processed faster than delimited fields.&lt;br /&gt;&lt;br /&gt;Advice&lt;br /&gt;------&lt;br /&gt;When runing single batch job, Delimited format is 2 times faster, a little more CPU used, less PGA memory.&lt;br /&gt;When runing multi concurrent batch jobs, Fixed-length format is better, and good for scale out,&lt;br /&gt; but Fixed-length format require more PGA memory and more physical reads, since the file size is bigger to hold the space.&lt;br /&gt;&lt;br /&gt;Solution&lt;br /&gt;--------&lt;br /&gt;Set up a typical emp test table, generate 700,000 rows, and run the benchmark.&lt;br /&gt;&lt;br /&gt;setup&lt;br /&gt;-----&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;drop TABLE EMP;&lt;br /&gt;CREATE TABLE EMP&lt;br /&gt;(&lt;br /&gt;  EMPNO     NUMBER(4)                           NOT NULL,&lt;br /&gt;  ENAME     VARCHAR2(10 BYTE),&lt;br /&gt;  JOB       VARCHAR2(9 BYTE),&lt;br /&gt;  MGR       NUMBER(4),&lt;br /&gt;  HIREDATE  DATE,&lt;br /&gt;  SAL       NUMBER(7,2),&lt;br /&gt;  COMM      NUMBER(7,2),&lt;br /&gt;  DEPTNO    NUMBER(2),&lt;br /&gt;  DML_TIME  TIMESTAMP(3)                        DEFAULT systimestamp&lt;br /&gt;)&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;alter table emp add CONSTRAINT EMP_PK&lt;br /&gt; PRIMARY KEY&lt;br /&gt; (EMPNO) using INDEX NOLOGGING&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;SET DEFINE OFF;&lt;br /&gt;&lt;br /&gt;Insert into SCOTT.EMP   (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO, DML_TIME)&lt;br /&gt; Values   (7369, 'SMITH', 'CLERK', 7902, TO_DATE('12/17/1980 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 30847.56, 20, TO_TIMESTAMP('2/2/2009 2:56:51.766 PM','fmMMfm/fmDDfm/YYYY fmHH12fm:MI:SS.FF AM'));&lt;br /&gt;Insert into SCOTT.EMP   (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO, DML_TIME)&lt;br /&gt; Values   (7499, 'ALLEN', 'SALESMAN', 7698, TO_DATE('02/20/1981 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 1600, 301, 30, TO_TIMESTAMP('2/2/2009 2:56:51.766 PM','fmMMfm/fmDDfm/YYYY fmHH12fm:MI:SS.FF AM'));&lt;br /&gt;Insert into SCOTT.EMP   (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO, DML_TIME)&lt;br /&gt; Values   (7521, 'WARD', 'SALESMAN', 7698, TO_DATE('02/22/1981 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 1250, 501, 30, TO_TIMESTAMP('2/2/2009 2:56:51.766 PM','fmMMfm/fmDDfm/YYYY fmHH12fm:MI:SS.FF AM'));&lt;br /&gt;Insert into SCOTT.EMP   (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO, DML_TIME)&lt;br /&gt; Values   (7566, 'JONES', 'MANAGER', 7839, TO_DATE('04/02/1981 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 2975, 20, TO_TIMESTAMP('2/2/2009 2:56:51.766 PM','fmMMfm/fmDDfm/YYYY fmHH12fm:MI:SS.FF AM'));&lt;br /&gt;Insert into SCOTT.EMP   (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO, DML_TIME)&lt;br /&gt; Values   (7654, 'MARTIN', 'SALESMAN', 7698, TO_DATE('09/28/1981 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 1250, 1401, 30, TO_TIMESTAMP('2/2/2009 2:56:51.766 PM','fmMMfm/fmDDfm/YYYY fmHH12fm:MI:SS.FF AM'));&lt;br /&gt;Insert into SCOTT.EMP   (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO, DML_TIME)&lt;br /&gt; Values   (7698, 'BLAKE', 'MANAGER', 7839, TO_DATE('05/01/1981 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 2850, 30, TO_TIMESTAMP('2/2/2009 2:56:51.766 PM','fmMMfm/fmDDfm/YYYY fmHH12fm:MI:SS.FF AM'));&lt;br /&gt;Insert into SCOTT.EMP   (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO, DML_TIME)&lt;br /&gt; Values   (7782, 'CLARK', 'MANAGER', 7839, TO_DATE('06/09/1981 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 2450, 10, TO_TIMESTAMP('2/2/2009 2:56:51.766 PM','fmMMfm/fmDDfm/YYYY fmHH12fm:MI:SS.FF AM'));&lt;br /&gt;Insert into SCOTT.EMP   (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO, DML_TIME)&lt;br /&gt; Values   (7788, 'SCOTT', 'ANALYST', 7566, TO_DATE('12/09/1982 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3000, 20, TO_TIMESTAMP('2/2/2009 2:56:51.766 PM','fmMMfm/fmDDfm/YYYY fmHH12fm:MI:SS.FF AM'));&lt;br /&gt;Insert into SCOTT.EMP   (EMPNO, ENAME, JOB, HIREDATE, SAL, DEPTNO, DML_TIME)&lt;br /&gt; Values   (7839, 'KING', 'PRESIDENT', TO_DATE('11/17/1981 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 5000, 10, TO_TIMESTAMP('2/2/2009 2:56:51.766 PM','fmMMfm/fmDDfm/YYYY fmHH12fm:MI:SS.FF AM'));&lt;br /&gt;Insert into SCOTT.EMP   (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO, DML_TIME)&lt;br /&gt; Values   (7844, 'TURNER', 'SALESMAN', 7698, TO_DATE('09/08/1981 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 1500, 1, 30, TO_TIMESTAMP('2/2/2009 2:56:51.766 PM','fmMMfm/fmDDfm/YYYY fmHH12fm:MI:SS.FF AM'));&lt;br /&gt;Insert into SCOTT.EMP   (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO, DML_TIME)&lt;br /&gt; Values   (7876, 'ADAMS', 'CLERK', 7788, TO_DATE('01/12/1983 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 1100, 20, TO_TIMESTAMP('2/2/2009 2:56:51.766 PM','fmMMfm/fmDDfm/YYYY fmHH12fm:MI:SS.FF AM'));&lt;br /&gt;Insert into SCOTT.EMP   (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO, DML_TIME)&lt;br /&gt; Values   (7900, 'JAMES', 'CLERK', 7698, TO_DATE('12/03/1981 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 950, 30, TO_TIMESTAMP('2/2/2009 2:56:51.766 PM','fmMMfm/fmDDfm/YYYY fmHH12fm:MI:SS.FF AM'));&lt;br /&gt;Insert into SCOTT.EMP   (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO, DML_TIME)&lt;br /&gt; Values   (7902, 'FORD', 'ANALYST', 7566, TO_DATE('12/03/1981 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3000, 20, TO_TIMESTAMP('2/2/2009 2:56:51.766 PM','fmMMfm/fmDDfm/YYYY fmHH12fm:MI:SS.FF AM'));&lt;br /&gt;Insert into SCOTT.EMP   (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO, DML_TIME)&lt;br /&gt; Values   (7934, 'MILLER', 'CLERK', 7782, TO_DATE('01/23/1982 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 1300, 10, TO_TIMESTAMP('2/2/2009 2:56:51.766 PM','fmMMfm/fmDDfm/YYYY fmHH12fm:MI:SS.FF AM'));&lt;br /&gt;COMMIT;&lt;br /&gt;&lt;br /&gt;CREATE OR REPLACE DIRECTORY data_dir AS '/u01/exp';&lt;br /&gt;&lt;br /&gt;set linesize 1000&lt;br /&gt;set pagesize 0&lt;br /&gt;set serveroutput off&lt;br /&gt;set trimspool on&lt;br /&gt;set trimout on&lt;br /&gt;set head off&lt;br /&gt;set echo off&lt;br /&gt;set term off&lt;br /&gt;set verify off&lt;br /&gt;set feedback off&lt;br /&gt;&lt;br /&gt;-- Fixed length format external table&lt;br /&gt;&lt;br /&gt;spool emp.txt&lt;br /&gt;with a as (select rownum from dual connect by level &lt;= 50000)&lt;br /&gt;select &lt;br /&gt;rpad(EMPNO, 10, ' ')||rpad(ENAME, 20, ' ')||rpad(job, 20, ' ')||trim(to_char(sal,'00000.00'))||' '&lt;br /&gt;||rpad(to_char(HIREDATE,'MM/DD/YYYY HH24:MI:SS'), 21, ' ')&lt;br /&gt;||rpad(to_char(systimestamp,'MM/DD/YYYY HH24:MI:SS.FF3'), 25, ' ')&lt;br /&gt;from scott.emp, a;&lt;br /&gt;spool off&lt;br /&gt;&lt;br /&gt;drop table emp_ext_fix;&lt;br /&gt;create table emp_ext_fix&lt;br /&gt;(&lt;br /&gt;  EMPNO     NUMBER(4) ,&lt;br /&gt;  ENAME     VARCHAR2(10 BYTE),&lt;br /&gt;  JOB       VARCHAR2(9 BYTE),&lt;br /&gt;  SAL       Number(7,2),&lt;br /&gt;  HIREDATE date,&lt;br /&gt;  DML_Time TIMESTAMP&lt;br /&gt;)&lt;br /&gt;organization external&lt;br /&gt;(type oracle_loader&lt;br /&gt; default directory data_dir&lt;br /&gt; access parameters&lt;br /&gt; (&lt;br /&gt; records delimited by newline&lt;br /&gt; DATE_CACHE 3000&lt;br /&gt; badfile data_dir:'emp.bad' &lt;br /&gt; logfile data_dir:'emp.log' &lt;br /&gt; fields LRtrim&lt;br /&gt; missing field values are null&lt;br /&gt; REJECT ROWS WITH ALL NULL FIELDS&lt;br /&gt;  ( &lt;br /&gt;   empno position(1:10) INTEGER EXTERNAL,&lt;br /&gt;   ename position(*:+20) CHAR ,&lt;br /&gt;   job   position(*:+20)  char ,&lt;br /&gt;   sal   position(*:+9) char ,&lt;br /&gt;   HIREDATE position(*:+21) DATE "MM/DD/YYYY HH24:MI:SS",&lt;br /&gt;   DML_TIME position(*:+25) CHAR(25) date_format TIMESTAMP MASK "MM/DD/YYYY HH24:MI:SS.FF3"&lt;br /&gt;  )&lt;br /&gt; ) &lt;br /&gt; LOCATION ('emp.txt') &lt;br /&gt;) &lt;br /&gt;NoPARALLEL &lt;br /&gt;REJECT LIMIT UNLIMITED; &lt;br /&gt;&lt;br /&gt;select * from EMP_ext_fix where rownum &lt; 5;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;--Tab delimited or csv file&lt;br /&gt;&lt;br /&gt;spool emp.csv&lt;br /&gt;with a as (select rownum from dual connect by level &lt;= 50000)&lt;br /&gt;select EMPNO||chr(9)||ENAME||chr(9)||job||chr(9)||sal||chr(9)&lt;br /&gt;||to_char(HIREDATE,'MM/DD/YYYY HH24:MI:SS')||chr(9)&lt;br /&gt;||to_char(systimestamp,'MM/DD/YYYY HH24:MI:SS.FF3')&lt;br /&gt;from scott.emp,a;&lt;br /&gt;spool off&lt;br /&gt;&lt;br /&gt;drop TABLE SCOTT.EMP_ext_csv;&lt;br /&gt;CREATE TABLE SCOTT.EMP_ext_csv&lt;br /&gt;(&lt;br /&gt;  EMPNO     NUMBER(4) ,&lt;br /&gt;  ENAME     VARCHAR2(10 BYTE),&lt;br /&gt;  JOB       VARCHAR2(9 BYTE),&lt;br /&gt;  SAL       Number(7,2),&lt;br /&gt;  HIREDATE date,&lt;br /&gt;  DML_Time TIMESTAMP&lt;br /&gt;)&lt;br /&gt;ORGANIZATION EXTERNAL&lt;br /&gt;    (&lt;br /&gt;           TYPE ORACLE_LOADER &lt;br /&gt;           DEFAULT DIRECTORY data_dir&lt;br /&gt;           ACCESS PARAMETERS &lt;br /&gt;           ( &lt;br /&gt;             records delimited by newline &lt;br /&gt;             badfile data_dir:'emp.bad' &lt;br /&gt;             logfile data_dir:'emp.log' &lt;br /&gt;             fields terminated by 0x'09' &lt;br /&gt;             missing field values are null &lt;br /&gt;             ( &lt;br /&gt;             EMPNO, ENAME, JOB, SAL, HIREDATE DATE "MM/DD/YYYY HH24:MI:SS",&lt;br /&gt;             dml_time char(25) date_format TIMESTAMP MASK "MM/DD/YYYY HH24:MI:SS.FF3"&lt;br /&gt;      ) &lt;br /&gt;           ) &lt;br /&gt;           LOCATION ('emp.csv') &lt;br /&gt;         ) &lt;br /&gt;         PARALLEL &lt;br /&gt;REJECT LIMIT UNLIMITED; &lt;br /&gt;select /* */ * from emp_ext_csv a where rownum &lt; 5;&lt;br /&gt;&lt;br /&gt;alter system flush buffer_cache;&lt;br /&gt;&lt;br /&gt;Benchmark&lt;br /&gt;---------&lt;br /&gt;&lt;br /&gt;exec runstats_pkg.rs_start;&lt;br /&gt;select count(HIREDATE) from emp_ext_csv;&lt;br /&gt;exec runstats_pkg.rs_middle;&lt;br /&gt;select count(HIREDATE) from emp_ext_fix;&lt;br /&gt;exec runstats_pkg.rs_stop;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;runstats_pkg.rs_start;&lt;br /&gt;for c in (select ename,sal,hiredate from emp_ext_csv)&lt;br /&gt;loop&lt;br /&gt;  Null;&lt;br /&gt;end loop;&lt;br /&gt;runstats_pkg.rs_middle;&lt;br /&gt;for c in (select ename,sal,hiredate from emp_ext_fix)&lt;br /&gt;loop&lt;br /&gt;  Null;&lt;br /&gt;end loop;&lt;br /&gt;runstats_pkg.rs_stop;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;runstats_pkg.rs_start;&lt;br /&gt;for c in (select * from emp_ext_fix)&lt;br /&gt;loop&lt;br /&gt;  Null;&lt;br /&gt;end loop;&lt;br /&gt;runstats_pkg.rs_middle;&lt;br /&gt;for c in (select * from emp_ext_csv)&lt;br /&gt;loop&lt;br /&gt;  Null;&lt;br /&gt;end loop;&lt;br /&gt;runstats_pkg.rs_stop;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;*) Output for last test case:&lt;br /&gt;&lt;br /&gt;Run1 ran in 179 hsecs&lt;br /&gt;Run2 ran in 91 hsecs&lt;br /&gt;run 1 ran in 196.7% of the time&lt;br /&gt;&lt;br /&gt;Name                                  Run1        Run2        Diff&lt;br /&gt;STAT...opened cursors current            1           0          -1&lt;br /&gt;STAT...user I/O wait time                3           2          -1&lt;br /&gt;STAT...db block changes                 36          37           1&lt;br /&gt;STAT...shared hash latch upgra           4           3          -1&lt;br /&gt;STAT...calls to kcmgas                   0           1           1&lt;br /&gt;STAT...redo ordering marks               0           1           1&lt;br /&gt;STAT...redo subscn max counts            0           1           1&lt;br /&gt;STAT...Batched IO single block           1           0          -1&lt;br /&gt;STAT...Batched IO block miss c           1           0          -1&lt;br /&gt;STAT...Batched IO double miss            1           0          -1&lt;br /&gt;STAT...active txn count during           0           1           1&lt;br /&gt;STAT...cleanout - number of kt           0           1           1&lt;br /&gt;STAT...queries parallelized              0           1           1&lt;br /&gt;STAT...DFO trees parallelized            0           1           1&lt;br /&gt;STAT...Parallel operations not           0           1           1&lt;br /&gt;LATCH.process allocation                 0           1           1&lt;br /&gt;LATCH.ksuosstats global area             0           1           1&lt;br /&gt;LATCH.OS process allocation              1           0          -1&lt;br /&gt;LATCH.KMG MMAN ready and start           1           0          -1&lt;br /&gt;LATCH.mostly latch-free SCN              0           1           1&lt;br /&gt;LATCH.lgwr LWN SCN                       0           1           1&lt;br /&gt;LATCH.Consistent RBA                     0           1           1&lt;br /&gt;LATCH.active checkpoint queue            1           0          -1&lt;br /&gt;LATCH.archive process latch              0           1           1&lt;br /&gt;LATCH.redo allocation                    3           4           1&lt;br /&gt;LATCH.list of block allocation           0           1           1&lt;br /&gt;LATCH.Change Notification Hash           1           0          -1&lt;br /&gt;LATCH.space background task la           1           0          -1&lt;br /&gt;LATCH.session timer                      1           0          -1&lt;br /&gt;LATCH.In memory undo latch               3           1          -2&lt;br /&gt;LATCH.job_queue_processes para           2           0          -2&lt;br /&gt;LATCH.ASM db client latch                0           2           2&lt;br /&gt;STAT...db block gets                    30          27          -3&lt;br /&gt;STAT...db block gets from cach          30          27          -3&lt;br /&gt;STAT...shared hash latch upgra           0           3           3&lt;br /&gt;LATCH.undo global data                   1           4           3&lt;br /&gt;LATCH.channel operations paren           7          11           4&lt;br /&gt;LATCH.redo writing                       1           5           4&lt;br /&gt;STAT...table scans (short tabl           1           6           5&lt;br /&gt;STAT...lob reads                         0           5           5&lt;br /&gt;STAT...undo change vector size       2,472       2,480           8&lt;br /&gt;STAT...session cursor cache hi           1          10           9&lt;br /&gt;STAT...free buffer requested            17           7         -10&lt;br /&gt;LATCH.messages                          16           6         -10&lt;br /&gt;LATCH.cache buffers lru chain           12           1         -11&lt;br /&gt;STAT...physical read total IO           13           0         -13&lt;br /&gt;STAT...physical reads                   13           0         -13&lt;br /&gt;STAT...physical reads cache             13           0         -13&lt;br /&gt;STAT...physical read IO reques          13           0         -13&lt;br /&gt;LATCH.enqueues                          82          68         -14&lt;br /&gt;LATCH.object queue header heap          16           1         -15&lt;br /&gt;LATCH.resmgr group change latc           0          16          16&lt;br /&gt;LATCH.resmgr:actses change gro           1          17          16&lt;br /&gt;LATCH.compile environment latc           0          16          16&lt;br /&gt;LATCH.PL/SQL warning settings            0          16          16&lt;br /&gt;LATCH.Real-time plan statistic           0          17          17&lt;br /&gt;LATCH.kokc descriptor allocati           2          20          18&lt;br /&gt;LATCH.parallel query stats               1          20          19&lt;br /&gt;STAT...CPU used by this sessio         179         202          23  ***&lt;br /&gt;STAT...recursive cpu usage             171         199          28&lt;br /&gt;LATCH.object queue header oper          34           6         -28&lt;br /&gt;STAT...enqueue releases                  5          34          29&lt;br /&gt;LATCH.session state list latch           3          32          29&lt;br /&gt;LATCH.simulator hash latch              14          45          31&lt;br /&gt;STAT...enqueue conversions               0          32          32&lt;br /&gt;LATCH.parameter table manageme           0          32          32&lt;br /&gt;LATCH.resmgr:free threads list           0          32          32&lt;br /&gt;LATCH.dummy allocation                   1          33          32&lt;br /&gt;LATCH.resmgr:active threads              0          32          32&lt;br /&gt;LATCH.error message lists                0          33          33&lt;br /&gt;STAT...session cursor cache co           7          43          36&lt;br /&gt;LATCH.JS queue state obj latch          36           0         -36&lt;br /&gt;STAT...enqueue requests                  5          50          45&lt;br /&gt;STAT...parse count (total)               7          53          46&lt;br /&gt;STAT...execute count                     7          53          46&lt;br /&gt;LATCH.enqueue hash chains               86         133          47&lt;br /&gt;LATCH.checkpoint queue latch            17          65          48&lt;br /&gt;STAT...workarea memory allocat         -26          37          63&lt;br /&gt;STAT...user calls                        0          64          64&lt;br /&gt;LATCH.query server freelists             1          68          67&lt;br /&gt;STAT...redo size                     2,976       3,044          68&lt;br /&gt;STAT...opened cursors cumulati           7          78          71&lt;br /&gt;LATCH.active service list                8          82          74&lt;br /&gt;LATCH.SQL memory manager worka           5          82          77&lt;br /&gt;STAT...Elapsed Time                    179          91         -88  ***&lt;br /&gt;STAT...index scans kdiixs1              18         108          90&lt;br /&gt;STAT...table scan blocks gotte          18         114          96&lt;br /&gt;LATCH.client/application info            1          97          96&lt;br /&gt;LATCH.process queue                      1          99          98&lt;br /&gt;LATCH.parallel query alloc buf           1         161         160&lt;br /&gt;LATCH.session idle bit                   3         167         164&lt;br /&gt;LATCH.session allocation                 3         189         186&lt;br /&gt;STAT...recursive calls               7,043       7,300         257&lt;br /&gt;STAT...no work - consistent re          77         474         397&lt;br /&gt;STAT...consistent gets from ca          75         490         415&lt;br /&gt;STAT...DB time                           0         421         421  xxx&lt;br /&gt;LATCH.shared pool                       14         517         503&lt;br /&gt;STAT...table fetch by rowid          1,695         186      -1,509&lt;br /&gt;STAT...calls to get snapshot s       1,697         129      -1,568&lt;br /&gt;LATCH.MinActiveScn Latch             1,689         106      -1,583&lt;br /&gt;STAT...rows fetched via callba       1,676          78      -1,598&lt;br /&gt;STAT...index fetch by key            1,676          68      -1,608&lt;br /&gt;LATCH.row cache objects                104       1,881       1,777&lt;br /&gt;STAT...table scan rows gotten          360       2,280       1,920&lt;br /&gt;STAT...buffer is not pinned co       3,415         533      -2,882&lt;br /&gt;LATCH.cache buffers chains           5,332       1,320      -4,012&lt;br /&gt;STAT...PX local messages recv            0       4,262       4,262&lt;br /&gt;STAT...PX local messages sent            0       4,262       4,262&lt;br /&gt;STAT...consistent gets               5,112         706      -4,406&lt;br /&gt;STAT...consistent gets from ca       5,112         706      -4,406&lt;br /&gt;STAT...session logical reads         5,142         733      -4,409&lt;br /&gt;STAT...consistent gets - exami       5,028         210      -4,818&lt;br /&gt;LATCH.process queue reference            1      58,878      58,877  ***&lt;br /&gt;STAT...cell physical IO interc     212,992           0    -212,992&lt;br /&gt;STAT...physical IO disk bytes      212,992           0    -212,992&lt;br /&gt;STAT...physical read total byt     212,992           0    -212,992&lt;br /&gt;STAT...physical read bytes         212,992           0    -212,992&lt;br /&gt;STAT...session uga memory max      604,728     115,320    -489,408&lt;br /&gt;STAT...session uga memory          604,728      84,664    -520,064&lt;br /&gt;STAT...session pga memory          720,896     131,072    -589,824&lt;br /&gt;STAT...session pga memory max      720,896     131,072    -589,824&lt;br /&gt;&lt;br /&gt;Run1 latches total versus runs -- difference and pct&lt;br /&gt;Run1        Run2        Diff       Pct&lt;br /&gt;7,629      64,444      56,815     11.84%&lt;br /&gt;&lt;br /&gt;PL/SQL procedure successfully completed.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Reference&lt;br /&gt;---------&lt;br /&gt;Oracle® Database Utilities 11g Release 1 (11.1)&lt;br /&gt;12  External Tables Concepts: Performance Hints When Using External Tables&lt;br /&gt;&lt;br /&gt;&lt;img style="cursor: pointer; width: 400px; height: 267px;" src="http://4.bp.blogspot.com/_Wv9Lui_cURQ/SYeVeKVm1II/AAAAAAAAAGY/TOb9-CKxeXM/s400/IMG_0023.jpg" alt="" id="BLOGGER_PHOTO_ID_5298367832028271746" border="0" /&gt;&lt;br /&gt;10 mile point&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-4104596770423106125?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/4104596770423106125/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=4104596770423106125' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/4104596770423106125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/4104596770423106125'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/02/external-table-benchmark-fixed-lenght.html' title='External table benchmark fixed-length vs. delimited format'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Wv9Lui_cURQ/SYeVeKVm1II/AAAAAAAAAGY/TOb9-CKxeXM/s72-c/IMG_0023.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-6741361410372123184</id><published>2009-01-22T21:36:00.000-08:00</published><updated>2009-01-22T21:38:28.835-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='10053 trace'/><category scheme='http://www.blogger.com/atom/ns#' term='dbms_xplan'/><title type='text'>Output from 10053 trace and dbms_xplan.display_cursor</title><content type='html'>Oracle 10.1.0.4 on RedHat Linux 3.0&lt;br /&gt;&lt;br /&gt;  *************************************&lt;br /&gt;  PARAMETERS WITH ALTERED VALUES&lt;br /&gt;  ******************************&lt;br /&gt;  parallel_threads_per_cpu            = 4&lt;br /&gt;  db_file_multiblock_read_count       = 32&lt;br /&gt;  optimizer_mode                      = first_rows_10&lt;br /&gt;  cursor_sharing                      = similar&lt;br /&gt;  optimizer_index_caching             = 25&lt;br /&gt;  query_rewrite_enabled               = false&lt;br /&gt;  query_rewrite_integrity             = stale_tolerated&lt;br /&gt;  optimizer_dynamic_sampling          = 0&lt;br /&gt;  *************************************&lt;br /&gt;  PARAMETERS WITH DEFAULT VALUES&lt;br /&gt;  ******************************&lt;br /&gt;  optimizer_features_enable           = 10.1.0.4&lt;br /&gt;&lt;br /&gt;***************************************&lt;br /&gt;BASE STATISTICAL INFORMATION&lt;br /&gt;***********************&lt;br /&gt;Table stats    Table: PO_ITEM   Alias: PO_ITEM&lt;br /&gt;  TOTAL ::  CDN: 81294  NBLKS:  3257  AVG_ROW_LEN:  132&lt;br /&gt;Index stats&lt;br /&gt;  Index: PO_ITEM_POID  COL#: 2&lt;br /&gt;    TOTAL ::  LVLS: 2   #LB: 365  #DK: 80100  LB/K: 1  DB/K: 1  CLUF: 3191&lt;br /&gt;  Index: PO_ITEM_STATUS_RANDOM_UPDDT  COL#: 4 6&lt;br /&gt;    TOTAL ::  LVLS: 2   #LB: 507  #DK: 80100  LB/K: 1  DB/K: 1  CLUF: 45647&lt;br /&gt;  Index: PO_ITEM_STATUS_UPDDT  COL#: 3 6&lt;br /&gt;    TOTAL ::  LVLS: 2   #LB: 507  #DK: 80100  LB/K: 1  DB/K: 1  CLUF: 80100&lt;br /&gt;***************************************&lt;br /&gt;SINGLE TABLE ACCESS PATH&lt;br /&gt;  COLUMN:       POID(NUMBER)  Col#: 2      Table: PO_ITEM   Alias: PO_ITEM&lt;br /&gt;    Size: 5  NDV: 80100  Nulls: 0  Density: 1.2484e-05 Min: 40  Max: 88988&lt;br /&gt;  COLUMN: STATUS_RAN(CHARACTER)  Col#: 4      Table: PO_ITEM   Alias: PO_ITEM&lt;br /&gt;    Size: 3  NDV: 20  Nulls: 0  Density: 6.1505e-06&lt;br /&gt;    Histogram: Freq  #Bkts: 20  UncompBkts: 3985  EndPtVals: 20&lt;br /&gt;  TABLE: PO_ITEM  Alias: PO_ITEM    &lt;br /&gt;    Original Card: 81294   Rounded: 1  Computed: 0.00  Non Adjusted: 0.00&lt;br /&gt;  Access Path: table-scan  Resc:  393  Resp:  393&lt;br /&gt;  Access Path: index (equal)&lt;br /&gt;    Index: PO_ITEM_POID&lt;br /&gt;    rsc_cpu: 24314   rsc_io: 4&lt;br /&gt;    ix_sel:  1.2670e-05    ix_sel_with_filters:  1.2670e-05&lt;br /&gt;  Access Path: index (scan)&lt;br /&gt;    Index: PO_ITEM_STATUS_RANDOM_UPDDT&lt;br /&gt;    rsc_cpu: 23778   rsc_io: 4&lt;br /&gt;    ix_sel:  6.2422e-06    ix_sel_with_filters:  6.2422e-06&lt;br /&gt;  Access Path: index (equal)&lt;br /&gt;    Index: PO_ITEM_POID&lt;br /&gt;    rsc_cpu: 17832   rsc_io: 3&lt;br /&gt;    ix_sel:  1.2670e-05    ix_sel_with_filters:  1.2670e-05&lt;br /&gt;  Access Path: index (index-only)&lt;br /&gt;    Index: PO_ITEM_STATUS_RANDOM_UPDDT&lt;br /&gt;    rsc_cpu: 17632   rsc_io: 3&lt;br /&gt;    ix_sel:  6.2422e-06    ix_sel_with_filters:  6.2422e-06&lt;br /&gt;    SORT resource      Sort statistics&lt;br /&gt;      Sort width:         148 Area size:      524288 Max Area size:    26214400&lt;br /&gt;      Degree:               1&lt;br /&gt;      Blocks to Sort:       1 Row size:           21 Total Rows:              1&lt;br /&gt;      Initial runs:         1 Merge passes:        0 IO Cost / pass:          0&lt;br /&gt;      Total IO sort cost: 0      Total CPU sort cost: 15225730&lt;br /&gt;      Total Temp space used: 0&lt;br /&gt;  BEST_CST: 4.00  PATH: 4  Degree:  1&lt;br /&gt;***************************************&lt;br /&gt;GENERAL PLANS&lt;br /&gt;***********************&lt;br /&gt;Join order[1]:  PO_ITEM[PO_ITEM]#0&lt;br /&gt;ORDER BY sort&lt;br /&gt;    SORT resource      Sort statistics&lt;br /&gt;      Sort width:         148 Area size:      524288 Max Area size:    26214400&lt;br /&gt;      Degree:               1&lt;br /&gt;      Blocks to Sort:       1 Row size:          156 Total Rows:              1&lt;br /&gt;      Initial runs:         1 Merge passes:        0 IO Cost / pass:          0&lt;br /&gt;      Total IO sort cost: 0      Total CPU sort cost: 15225730&lt;br /&gt;      Total Temp space used: 0&lt;br /&gt;Best so far: TABLE#: 0  CST:          5  CDN:          1  BYTES:        132&lt;br /&gt;(newjo-stop-1) k:0, spcnt:0, perm:1, maxperm:80000&lt;br /&gt;    SORT resource      Sort statistics&lt;br /&gt;      Sort width:         148 Area size:      524288 Max Area size:    26214400&lt;br /&gt;      Degree:               1&lt;br /&gt;      Blocks to Sort:       1 Row size:          156 Total Rows:              1&lt;br /&gt;      Initial runs:         1 Merge passes:        0 IO Cost / pass:          0&lt;br /&gt;      Total IO sort cost: 0      Total CPU sort cost: 15225730&lt;br /&gt;      Total Temp space used: 0&lt;br /&gt;Final - All Rows Plan:&lt;br /&gt;  JOIN ORDER: 1&lt;br /&gt;  CST: 5  CDN: 1  RSC: 5  RSP: 5  BYTES: 132&lt;br /&gt;  IO-RSC: 4  IO-RSP: 4  CPU-RSC: 15249507  CPU-RSP: 15249507&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;SQL&gt; SELECT /*+ gather_plan_statistics  */ * FROM po_item WHERE poid = :a AND STATUS_random = :b ORDER BY poitemid;&lt;br /&gt;&lt;br /&gt;SQL&gt; SELECT * FROM table (Cast(dbms_xplan.display_cursor(NULL,NULL, 'runstats_last') as SYS.DBMS_XPLAN_TYPE_TABLE));&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;-----------------&lt;br /&gt;&lt;br /&gt;SQL_ID  cp44zcmqma34f, child number 0&lt;br /&gt;-------------------------------------&lt;br /&gt;SELECT /*+ gather_plan_statistics  */ * FROM po_item WHERE poid = :a AND STATUS_random = :b ORDER BY poitemid&lt;br /&gt;&lt;br /&gt;Plan hash value: 3970202189&lt;br /&gt;&lt;br /&gt;------------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                   | Name                        | E-Rows | A-Rows | Buffers | Reads  | Writes | A-Time     |&lt;br /&gt;------------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;|   1 | SORT ORDER BY               |                             |      1 |      0 |    2377 | 0 |      0 |00:00:00.01 |&lt;br /&gt;|*  2 |  TABLE ACCESS BY INDEX ROWID| PO_ITEM                     |      1 |      0 |    2377 | 0 |      0 |00:00:00.01 |&lt;br /&gt;|*  3 |   INDEX RANGE SCAN          | PO_ITEM_STATUS_RANDOM_UPDDT |      1 |   4153 |      29 | 0 |      0 |00:00:00.02 |&lt;br /&gt;------------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Query Block Name / Object Alias (identified by operation id):&lt;br /&gt;-------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;   1 - SEL$1&lt;br /&gt;   2 - SEL$1 / PO_ITEM@SEL$1&lt;br /&gt;   3 - SEL$1 / PO_ITEM@SEL$1&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   2 - filter("POID"=:A)&lt;br /&gt;   3 - access("STATUS_RANDOM"=:B)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;27 rows selected.&lt;br /&gt;&lt;br /&gt;SQL&gt; set autot on&lt;br /&gt;SQL&gt;&lt;br /&gt;SELECT /*  */ * FROM po_item WHERE poid = :a AND STATUS_random = :b ORDER BY poitemid;&lt;br /&gt;&lt;br /&gt;no rows selected&lt;br /&gt;&lt;br /&gt;Execution Plan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;Plan hash value: 3115544074&lt;br /&gt;&lt;br /&gt;---------------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                    | Name         | Rows  | Bytes | Cost (%CPU)| Time     |&lt;br /&gt;---------------------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT             |              |     1 |   132 |     5  (20)| 00:00:01 |&lt;br /&gt;|   1 |  SORT ORDER BY               |              |     1 |   132 |     5  (20)| 00:00:01 |&lt;br /&gt;|*  2 |   TABLE ACCESS BY INDEX ROWID| PO_ITEM      |     1 |   132 |     4   (0)| 00:00:01 |&lt;br /&gt;|*  3 |    INDEX RANGE SCAN          | PO_ITEM_POID |     1 |       |     3   (0)| 00:00:01 |&lt;br /&gt;---------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   2 - filter("STATUS_RANDOM"=:B)&lt;br /&gt;   3 - access("POID"=TO_NUMBER(:A))&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-6741361410372123184?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/6741361410372123184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=6741361410372123184' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/6741361410372123184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/6741361410372123184'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/01/output-from-10053-trace-and.html' title='Output from 10053 trace and dbms_xplan.display_cursor'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-5851620630165719307</id><published>2009-01-22T20:33:00.000-08:00</published><updated>2009-01-22T22:04:25.647-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='histogram'/><category scheme='http://www.blogger.com/atom/ns#' term='CBO'/><category scheme='http://www.blogger.com/atom/ns#' term='selectivity'/><category scheme='http://www.blogger.com/atom/ns#' term='density'/><title type='text'>Fix SQL index access path issue with 10053 trace and hack the stats</title><content type='html'>Goal&lt;br /&gt;----&lt;br /&gt;Find out why SQL optimizer select a bad index access path when there are 2 predicates,&lt;br /&gt;and each predicate column got an index created on it.&lt;br /&gt;&lt;br /&gt;# SQL&lt;br /&gt;SELECT /*  */ * FROM po_item WHERE poid = :a AND STATUS = :b ORDER BY poitemid;&lt;br /&gt;&lt;br /&gt;INDEX PO_ITEM_POID ON PO_ITEM(POID)&lt;br /&gt;INDEX PO_ITEM_STATUS_UPDDT ON PO_ITEM(STATUS, STATUSUPDDT)&lt;br /&gt;&lt;br /&gt;It should access data by index on POID column, but it suddenly changed to use index on STATUS column.&lt;br /&gt;&lt;br /&gt;Solution&lt;br /&gt;--------&lt;br /&gt;Understand CBO,experiment,observe and interpret.&lt;br /&gt;With SQL session 10053 trace and dbms_xplan.display_cursor().&lt;br /&gt;&lt;br /&gt;Result&lt;br /&gt;------&lt;br /&gt;When database collect histogram stats on a column, it calculate a new density for the column,&lt;br /&gt;and it will be extreme smaller, CBO use density as selectivity.&lt;br /&gt;After we hack the column density, database will clear the histogram stats,&lt;br /&gt;the CBO will use 1/NumberOfDistinct, ignore density.&lt;br /&gt;&lt;br /&gt;When we check the output of 10053 trace,&lt;br /&gt;both IO costs are same, but index selectivity (ix_sel) and table selectivity (ix_sel_with_filters)&lt;br /&gt;on Index: PO_ITEM_STATUS_RANDOM_UPDDT is smaller than than it on Index: PO_ITEM_POID.&lt;br /&gt;&lt;br /&gt;  Access Path: index (equal)&lt;br /&gt;    Index: PO_ITEM_POID&lt;br /&gt;    rsc_cpu: 17832   rsc_io: 3&lt;br /&gt;    ix_sel:  1.2670e-05    ix_sel_with_filters:  1.2670e-05&lt;br /&gt;  Access Path: index (index-only)&lt;br /&gt;    Index: PO_ITEM_STATUS_RANDOM_UPDDT&lt;br /&gt;    rsc_cpu: 17632   rsc_io: 3&lt;br /&gt;    ix_sel:  6.2422e-06    ix_sel_with_filters:  6.2422e-06&lt;br /&gt;&lt;br /&gt;*) Fix: hack the density, make it accurate.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://mujiang.blogspot.com/2009/01/output-from-10053-trace-and.html"&gt;&lt;br /&gt;10053 trace output and dbms_xplan page link.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Experiment&lt;br /&gt;----------&lt;br /&gt;&lt;br /&gt;InBox&lt;br /&gt;-----&lt;br /&gt;&lt;br /&gt;Next Action&lt;br /&gt;-----------&lt;br /&gt;&lt;br /&gt;Complete&lt;br /&gt;--------&lt;br /&gt;create test table po_item&lt;br /&gt;- evenly distribution Mod(), value from '01' to '20'&lt;br /&gt;- random distribution dbms_random.value() '01' to '20'&lt;br /&gt;- normal distribution dbms_random.normal() '01' to '99'&lt;br /&gt;create index&lt;br /&gt;collect table stats&lt;br /&gt;collect column STATUS histogram stats&lt;br /&gt;-- This step skipped: run SQL UPDATE to generate required data distribution&lt;br /&gt;run SQL&lt;br /&gt;- enable 10053 trace&lt;br /&gt;- dbms_xplan.display_cursor()&lt;br /&gt;- set autotrace on&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;*) Purchase_Order Item table&lt;br /&gt;&lt;br /&gt;drop TABLE PO_ITEM;&lt;br /&gt;CREATE TABLE PO_ITEM&lt;br /&gt;(&lt;br /&gt;POITEMID NUMBER(8),&lt;br /&gt;POID NUMBER(8),&lt;br /&gt;STATUS CHAR(2 BYTE),&lt;br /&gt;STATUS_random CHAR(2 BYTE),&lt;br /&gt;STATUS_normal CHAR(2 BYTE),&lt;br /&gt;STATUSUPDDT DATE,&lt;br /&gt;ITEMTITLE VARCHAR2(50 BYTE),&lt;br /&gt;ITEMAUTHOR VARCHAR2(50 BYTE),&lt;br /&gt;ITEMPRICE NUMBER(8,2)&lt;br /&gt;)&lt;br /&gt;nologging;&lt;br /&gt;&lt;br /&gt;execute dbms_random.seed(0)&lt;br /&gt;&lt;br /&gt;insert /*+ append */ into po_item&lt;br /&gt;with g as (&lt;br /&gt;select -- materialize&lt;br /&gt;level&lt;br /&gt;from dual&lt;br /&gt;connect by level &lt;= 2000&lt;br /&gt;)&lt;br /&gt;select&lt;br /&gt;/*+ leading(v1,v2,v3) use_nl(v2) use_nl(v3) */&lt;br /&gt; rownum&lt;br /&gt;,Round(rownum/0.9,0)&lt;br /&gt;,To_Char(Round(Mod(rownum,100)))&lt;br /&gt;,To_Char(Round(dbms_random.value(1,20)))&lt;br /&gt;,LTrim(To_Char(ABS(Mod(10 * dbms_random.normal,100)),'99'))&lt;br /&gt;,To_Date('1999','YYYY') + rownum/86400&lt;br /&gt;,rpad(rownum,50,'x')&lt;br /&gt;,rpad(rownum,50,'*')&lt;br /&gt;,Round(dbms_random.value(1,100),2)&lt;br /&gt;from&lt;br /&gt; g v1&lt;br /&gt;,g v2&lt;br /&gt;,g v3&lt;br /&gt;where&lt;br /&gt;rownum &lt;= 80100;&lt;br /&gt;&lt;br /&gt;commit;&lt;br /&gt;exec dbms_stats.gather_table_stats(user,'PO_ITEM');&lt;br /&gt;&lt;br /&gt;-- Index on POID column&lt;br /&gt;&lt;br /&gt;CREATE INDEX PO_ITEM_POID ON PO_ITEM&lt;br /&gt;(POID)&lt;br /&gt;NoLogging;&lt;br /&gt;&lt;br /&gt;-- Index on column STATUS and STATUS_UPD_DATE&lt;br /&gt;&lt;br /&gt;CREATE INDEX PO_ITEM_STATUS_UPDDT ON PO_ITEM&lt;br /&gt;(STATUS, STATUSUPDDT)&lt;br /&gt;NoLogging;&lt;br /&gt;&lt;br /&gt;-- Index on column STATUS_random and STATUS_UPD_DATE&lt;br /&gt;&lt;br /&gt;CREATE INDEX PO_ITEM_STATUS_RANDOM_UPDDT ON PO_ITEM&lt;br /&gt;(STATUS_random, STATUSUPDDT)&lt;br /&gt;NoLogging;&lt;br /&gt;&lt;br /&gt;exec dbms_stats.gather_table_stats(user,'PO_ITEM');&lt;br /&gt;&lt;br /&gt;*) init parameter&lt;br /&gt;alter system set optimizer_index_cost_adj=25;&lt;br /&gt;alter system set optimizer_index_cost_adj=100;&lt;br /&gt;alter system set optimizer_index_caching=0;&lt;br /&gt;alter system set optimizer_index_caching=25;&lt;br /&gt;alter system set optimizer_mode = FIRST_ROWS_10;&lt;br /&gt;alter system flush shared_pool;&lt;br /&gt;alter system flush BUFFER_CACHE;&lt;br /&gt;&lt;br /&gt;set autot off&lt;br /&gt;set serveroutput off&lt;br /&gt;variable a NUMBER;&lt;br /&gt;variable b VARCHAR2(2);&lt;br /&gt;&lt;br /&gt;exec :a := 72036876;&lt;br /&gt;exec :a := 70100;&lt;br /&gt;exec :b := '98';&lt;br /&gt;exec :b := '17';&lt;br /&gt;&lt;br /&gt;*) enable 10053 trace&lt;br /&gt;&lt;br /&gt;ALTER SESSION SET TRACEFILE_IDENTIFIER="i";&lt;br /&gt;ALTER SESSION SET EVENTS '10053 trace name context forever, level 1';&lt;br /&gt;&lt;br /&gt;SELECT /*  */ * FROM po_item WHERE poid = :a AND STATUS = :b ORDER BY poitemid;&lt;br /&gt;SELECT /*  */ * FROM po_item WHERE poid = :a AND STATUS_random = :b ORDER BY poitemid;&lt;br /&gt;SELECT * FROM table (DBMS_XPLAN.DISPLAY_CURSOR);&lt;br /&gt;&lt;br /&gt;alter session set events '10053 trace name context off';&lt;br /&gt;&lt;br /&gt;*) display SQL execution plan&lt;br /&gt;&lt;br /&gt;-- uses the hint gather_plan_statistics to enable the generation of the execution statistics.&lt;br /&gt;set linesize 300&lt;br /&gt;SELECT /*+ gather_plan_statistics  */ * FROM po_item WHERE poid = :a AND STATUS = :b ORDER BY poitemid;&lt;br /&gt;SELECT * FROM table (Cast(dbms_xplan.display_cursor(NULL,NULL, 'runstats_last') as SYS.DBMS_XPLAN_TYPE_TABLE));&lt;br /&gt;&lt;br /&gt;SELECT /*+ gather_plan_statistics  */ * FROM po_item WHERE poid = :a AND STATUS_random = :b ORDER BY poitemid;&lt;br /&gt;SELECT * FROM table (Cast(dbms_xplan.display_cursor(NULL,NULL, 'runstats_last') as SYS.DBMS_XPLAN_TYPE_TABLE));&lt;br /&gt;&lt;br /&gt;set autot trace exp&lt;br /&gt;SELECT /*+ gather_plan_statistics  */ * FROM po_item WHERE poid = :a AND STATUS = :b ORDER BY poitemid;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- gather histogram stats on column STATUS&lt;br /&gt;begin&lt;br /&gt;dbms_stats.gather_table_stats(&lt;br /&gt;user,&lt;br /&gt;'po_item',&lt;br /&gt;cascade =&gt; true,&lt;br /&gt;estimate_percent =&gt; 0.1,&lt;br /&gt;method_opt =&gt; 'for columns size 254 status,status_random,status_normal size 100'&lt;br /&gt;);&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;-- hack column stats&lt;br /&gt;begin&lt;br /&gt;DBMS_STATS.SET_COLUMN_STATS (&lt;br /&gt;   ownname =&gt;       USER,&lt;br /&gt;   tabname =&gt;       'PO_ITEM',&lt;br /&gt;   colname =&gt;       'STATUS',&lt;br /&gt;--   distcnt =&gt; 20,&lt;br /&gt;   density =&gt; 0.05,&lt;br /&gt;   force =&gt; True&lt;br /&gt; );&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- Compare index access on right index&lt;br /&gt;set autot trace&lt;br /&gt;&lt;br /&gt;SELECT /*+ index(po_item,PO_ITEM_POID) */ * FROM PO_ITEM&lt;br /&gt;WHERE poid = :a AND STATUS = :b ORDER BY poitemid;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Reference&lt;br /&gt;---------&lt;br /&gt;*) origianl table and SQL:&lt;br /&gt;abedba.ABEPOITEMS&lt;br /&gt;SELECT /*  */ * FROM ABEPOITEMS WHERE ABEPOID = :a AND STATUS = :b ORDER BY ABEPOITEMID;&lt;br /&gt;&lt;br /&gt;*) Get stats&lt;br /&gt;&lt;br /&gt;-- Display table stats&lt;br /&gt;set autot off&lt;br /&gt;set SQLPATH=A:\maint\monitor;A:\adm\maint&lt;br /&gt;&lt;br /&gt;@table scott po_item&lt;br /&gt;&lt;br /&gt;-- check CBO parameter&lt;br /&gt;select name,value,isdefault from v$sql_optimizer_env&lt;br /&gt;where sql_id = 'cp44zcmqma34f';&lt;br /&gt;&lt;br /&gt;-- Query to check the value of input hidden "parameter_name"&lt;br /&gt;col indx format 9999&lt;br /&gt;col inst_id heading "INST" format 9999&lt;br /&gt;col ksppinm heading "NAME" format a30&lt;br /&gt;col ksppdesc heading "DESC" format a40&lt;br /&gt;col ksppstvl heading "CURR VAL" format a15&lt;br /&gt;col ksppstdvl heading "DEFAULT VAL" format a15&lt;br /&gt;&lt;br /&gt;set echo on&lt;br /&gt;set autot off&lt;br /&gt;select v.indx,v.inst_id,ksppinm p_name,ksppstvl curr_val,ksppstdvl default_val,ksppdesc p_desc&lt;br /&gt;from x$ksppi i ,x$ksppcv v&lt;br /&gt;where i.indx=v.indx and ksppinm like '%sort_elimination_cost_ratio%';&lt;br /&gt;&lt;br /&gt;-- display real value for low_value and high_value on view user_tab_col_statistics&lt;br /&gt;DECLARE&lt;br /&gt;l_low_value user_tab_col_statistics.low_value%TYPE;&lt;br /&gt;l_high_value user_tab_col_statistics.high_value%TYPE;&lt;br /&gt;l_val1 ABEPOITEMS.STATUS%TYPE;&lt;br /&gt;BEGIN&lt;br /&gt;SELECT low_value, high_value&lt;br /&gt;INTO l_low_value, l_high_value&lt;br /&gt;FROM user_tab_col_statistics&lt;br /&gt;WHERE table_name = 'PO_ITEM'&lt;br /&gt; AND column_name = 'STATUS';&lt;br /&gt;&lt;br /&gt; dbms_stats.convert_raw_value(l_low_value, l_val1);&lt;br /&gt; dbms_output.put_line('low_value: ' || l_val1);&lt;br /&gt; dbms_stats.convert_raw_value(l_high_value, l_val1);&lt;br /&gt; dbms_output.put_line('high_value: ' || l_val1);&lt;br /&gt;&lt;br /&gt; dbms_output.put_line('high_value: ' || l_low_value||', '||l_high_value);&lt;br /&gt;&lt;br /&gt;END;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;exec DBMS_STATS.UnLOCK_TABLE_STATS(user,'ABEPOitemS');&lt;br /&gt;&lt;br /&gt;-- Verify data distribution&lt;br /&gt;select status,count(*)&lt;br /&gt;from abedba.po_item&lt;br /&gt;group by status;&lt;br /&gt;&lt;br /&gt;STATUS    COUNT(*)&lt;br /&gt;01    2795&lt;br /&gt;04    619&lt;br /&gt;05    252&lt;br /&gt;10    1334827&lt;br /&gt;11    7298222&lt;br /&gt;12    232920&lt;br /&gt;14    313380&lt;br /&gt;15    1912919&lt;br /&gt;16    8764&lt;br /&gt;17    233443&lt;br /&gt;18    116935&lt;br /&gt;19    549803&lt;br /&gt;24    748465&lt;br /&gt;25    356031&lt;br /&gt;35    12905639&lt;br /&gt;45    7594712&lt;br /&gt;50    235&lt;br /&gt;51    75338&lt;br /&gt;52    334234&lt;br /&gt;53    22&lt;br /&gt;54    22325&lt;br /&gt;55    5110&lt;br /&gt;56    12311&lt;br /&gt;60    3&lt;br /&gt;66    245&lt;br /&gt;90    215&lt;br /&gt;97    54017&lt;br /&gt;98    83&lt;br /&gt;--&lt;br /&gt;&lt;br /&gt;*) hack object stats&lt;br /&gt;&lt;br /&gt;-- hack index stats. --old 3931, new 40100&lt;br /&gt;begin&lt;br /&gt;DBMS_STATS.SET_INDEX_STATS (&lt;br /&gt;   ownname =&gt; USER,&lt;br /&gt;   indname =&gt; 'PO_ITEM_POID',&lt;br /&gt;   clstfct =&gt; 50);&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;DBMS_STATS.SET_INDEX_STATS (&lt;br /&gt;   ownname =&gt; 'SCOTT',&lt;br /&gt;   indname =&gt; 'PO_ITEM_STATUS_UPDDT',&lt;br /&gt;   clstfct =&gt; 1000);&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;-- hack column stats&lt;br /&gt;begin&lt;br /&gt;DBMS_STATS.SET_COLUMN_STATS (&lt;br /&gt;   ownname =&gt;       USER,&lt;br /&gt;   tabname =&gt;       'PO_ITEM',&lt;br /&gt;   colname =&gt;       'STATUS',&lt;br /&gt;   density =&gt; 0.05);&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;*) Export and Import the table stats&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;dbms_stats.create_stat_table(ownname =&gt; user,&lt;br /&gt;stattab =&gt; 'MYSTATS',&lt;br /&gt;tblspace =&gt; 'USERS');&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;DBMS_STATS.EXPORT_TABLE_STATS (&lt;br /&gt;   ownname  =&gt; USER,&lt;br /&gt;   tabname  =&gt; 'PO_ITEM',&lt;br /&gt;   stattab  =&gt; 'MYSTATS');&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;exec dbms_stats.delete_table_stats(ownname =&gt; user,tabname =&gt; 'PO_ITEM')&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;DBMS_STATS.IMPORT_TABLE_STATS (&lt;br /&gt;   ownname  =&gt; USER,&lt;br /&gt;   tabname  =&gt; 'PO_ITEM',&lt;br /&gt;   stattab  =&gt; 'MYSTATS',&lt;br /&gt;   force =&gt; true);&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;*) others&lt;br /&gt;&lt;br /&gt;-- Tune sort index over the access predicate index&lt;br /&gt;alter session set "_sort_elimination_cost_ratio" = 0;&lt;br /&gt;&lt;br /&gt;SELECT /*x index(po_item,PO_ITEM_STATUS_UPDDT) */ * FROM PO_ITEM&lt;br /&gt;WHERE poid = :a AND STATUS = :b ORDER BY poitemid;&lt;br /&gt;&lt;br /&gt;alter session set "_sort_elimination_cost_ratio" = 1;&lt;br /&gt;&lt;br /&gt;SELECT /*x index(po_item,PO_ITEM_STATUS_UPDDT) */ * FROM PO_ITEM&lt;br /&gt;WHERE poid = :a AND STATUS = :b ORDER BY poitemid;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Wv9Lui_cURQ/SXlXChC78UI/AAAAAAAAAF4/zNaO_RCrimg/s1600-h/PICT1247.JPG"&gt;&lt;img style="cursor: pointer; width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_Wv9Lui_cURQ/SXlXChC78UI/AAAAAAAAAF4/zNaO_RCrimg/s400/PICT1247.JPG" alt="" id="BLOGGER_PHOTO_ID_5294358537692770626" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;QingDao, China&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-5851620630165719307?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/5851620630165719307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=5851620630165719307' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/5851620630165719307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/5851620630165719307'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/01/fix-sql-index-access-path-issue-with.html' title='Fix SQL index access path issue with 10053 trace and hack the stats'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Wv9Lui_cURQ/SXlXChC78UI/AAAAAAAAAF4/zNaO_RCrimg/s72-c/PICT1247.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-4036620500547277166</id><published>2009-01-14T11:27:00.000-08:00</published><updated>2009-04-14T14:49:29.255-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='asynchronous process'/><category scheme='http://www.blogger.com/atom/ns#' term='partition'/><category scheme='http://www.blogger.com/atom/ns#' term='split function'/><category scheme='http://www.blogger.com/atom/ns#' term='BASE'/><title type='text'>Overview asynchronous process change data</title><content type='html'>Goal&lt;br /&gt;----&lt;br /&gt;Split function :F1 from funcation :F2, asynchronous the process,&lt;br /&gt;to gain scalability(performance and reliability) and availability.&lt;br /&gt;&lt;br /&gt;:F1 = check deleted book&lt;br /&gt;:F2 = upload inventory data&lt;br /&gt;&lt;br /&gt;*) Business logic background for this example&lt;br /&gt;&lt;br /&gt;In our 4 node RAC database, :F2 = upload inventory data runs on node 4,&lt;br /&gt;:F1 = check deleted book runs on node 1 frequently, 50 times/second;&lt;br /&gt;:F1 is hitting the data randomly, 30 rows a page will probably touch 30 data blocks.&lt;br /&gt;This caused lots of Global Cache inter-connect traffic from node 4 to node 1.&lt;br /&gt;Based on our AWR report, it is&lt;br /&gt;&lt;br /&gt; Network band width:&lt;br /&gt;= Network requests * db_block_size&lt;br /&gt;= 218104 * 4096&lt;br /&gt;= 893,353,984 (Transfer about 900Mbytes data in 15 minutes)&lt;br /&gt;&lt;br /&gt;After implement asynchronous process, the GC transfer volume reduced 200 times for this function,&lt;br /&gt;&lt;br /&gt;The F1 check deleted book performance SLA improved 100 times.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Wv9Lui_cURQ/SW4922hEflI/AAAAAAAAAFQ/HxAOoRopgJo/s1600-h/book_del_check.jpg"&gt;&lt;img style="cursor: pointer; width: 330px; height: 400px;" src="http://4.bp.blogspot.com/_Wv9Lui_cURQ/SW4922hEflI/AAAAAAAAAFQ/HxAOoRopgJo/s400/book_del_check.jpg" alt="" id="BLOGGER_PHOTO_ID_5291234624763362898" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Figure-1: Topology  process diagram&lt;br /&gt;&lt;br /&gt;*) Keyword: Loose coupling, Function split, Partition data by function and range/key list.&lt;br /&gt;&lt;br /&gt;Solution&lt;br /&gt;--------&lt;br /&gt;Queue the change data (deleted book listing_id) into a staging table,&lt;br /&gt;batch process and merge it to target table (book_delete_check) every N minutes,&lt;br /&gt;to reduce the network traffic.&lt;br /&gt;&lt;br /&gt;*) Understanding: we will lose unprocessed data if we use SQL start date as end tag timestamp&lt;br /&gt;*) Experiment and Observation:&lt;br /&gt; - replace Synonym will not require DDL lock, not safe&lt;br /&gt; - in MERGE SQL, DELETE share UPDATE predicate, and will not delete INSERT rows&lt;br /&gt; - query gv$ view may fail in a RAC database when there is not enough parallel processes on each instance&lt;br /&gt;*) Interpretation: use predicate stage_table.update_date &lt; v$transaction.start_date&lt;br /&gt;&lt;br /&gt;Approach&lt;br /&gt;--------&lt;br /&gt;&lt;br /&gt;*) mark rowid into a temporary table, process and delete by rowid in the temporary table&lt;br /&gt;*) update_date &lt; Least(SysDate,v$transaction.start_date)&lt;br /&gt;*) SCN_TO_TIMESTAMP(ORA_ROWSCN) &lt; sysdate&lt;br /&gt; - http://www.ningoo.net/html/2009/about_ora_rowscn.html&lt;br /&gt;*) Exchange one data partition with a swap table&lt;br /&gt;*) RETURNING rows BULK COLLECT INTO UDT(User Define Type schema object collection)&lt;br /&gt;*) Many partitions on Mod(to_number(to_char(update_date,'MI')),10)&lt;br /&gt; - Partition table to spread the DDL/DML lock contention&lt;br /&gt; - so N partitions on a centain interval based on your transaction volume and DML lock frequency&lt;br /&gt; - exchange each partion to each swap table&lt;br /&gt; - process the swap table&lt;br /&gt; - truncate the swap table&lt;br /&gt; - the DDL lock will not happen very often&lt;br /&gt; - if partition locked, insert a row to stage_proc_lock table&lt;br /&gt; - if partition locked 4 times continuously&lt;br /&gt;  # process one partition with one of above single table method&lt;br /&gt;  # delete the locked partition log row&lt;br /&gt;*) Partition view on heap tables for Oracle Standard Edition&lt;br /&gt;*) Oracle Stream&lt;br /&gt;*) Oracle AQ&lt;br /&gt;*) Other Messaging tool&lt;br /&gt;&lt;br /&gt;Setup&lt;br /&gt;-----&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-- target table&lt;br /&gt;drop table book_del_check;&lt;br /&gt;&lt;br /&gt;create table book_del_check&lt;br /&gt;(&lt;br /&gt;  listingsid  number(20),&lt;br /&gt;  upd_dd      number(2)&lt;br /&gt;, constraint  book_del_check_pk primary key (listingsid )&lt;br /&gt;)&lt;br /&gt;organization index&lt;br /&gt;including upd_dd&lt;br /&gt;overflow&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;-- staging table&lt;br /&gt;-- Option n+2, for small TX volume&lt;br /&gt;drop table book_delete_stage;&lt;br /&gt;&lt;br /&gt;create table book_delete_stage(&lt;br /&gt;listingsid number(20),&lt;br /&gt;qty number(5),&lt;br /&gt;delete_flag number(1),&lt;br /&gt;update_date date default sysdate&lt;br /&gt;)&lt;br /&gt;ROWDEPENDENCIES&lt;br /&gt;nologging;&lt;br /&gt;&lt;br /&gt;create or replace view book_delete_stage_v&lt;br /&gt;as&lt;br /&gt; select listingsid, delete_flag, To_Number(To_Char(update_date,'DD')) upd_day, upd_time&lt;br /&gt; from&lt;br /&gt; (SELECT listingsid, delete_flag,update_date,&lt;br /&gt;   SCN_TO_TIMESTAMP(ORA_ROWSCN) upd_time,&lt;br /&gt;   Row_Number() OVER (PARTITION BY listingsid order by update_date desc) rn&lt;br /&gt;  FROM book_delete_stage b&lt;br /&gt; )&lt;br /&gt; where rn = 1&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;drop TYPE book_chg_tab;&lt;br /&gt;drop TYPE book_chg_rec;&lt;br /&gt;&lt;br /&gt;create or replace TYPE book_chg_rec AS OBJECT&lt;br /&gt;(&lt;br /&gt;listingsid number(20),&lt;br /&gt;qty number(5),&lt;br /&gt;delete_flag number(1),&lt;br /&gt;update_date timestamp(3)&lt;br /&gt;);&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;create or replace TYPE book_chg_tab IS TABLE OF book_chg_rec;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;drop table gt_book_delete_stage_i;&lt;br /&gt;drop table gt_book_delete_stage_d;&lt;br /&gt;drop table gt_book_delete_stage_rid;&lt;br /&gt;&lt;br /&gt;create global temporary table gt_book_delete_stage_i&lt;br /&gt;(&lt;br /&gt;listingsid number(20),&lt;br /&gt;qty number(5)&lt;br /&gt;)&lt;br /&gt;ON COMMIT DELETE ROWS&lt;br /&gt;;&lt;br /&gt;create global temporary table gt_book_delete_stage_d&lt;br /&gt;(&lt;br /&gt;listingsid number(20),&lt;br /&gt;qty number(5)&lt;br /&gt;)&lt;br /&gt;ON COMMIT DELETE ROWS&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;create global temporary table gt_book_delete_stage_rid&lt;br /&gt;(&lt;br /&gt;rid rowid,&lt;br /&gt;listingsid number(20)&lt;br /&gt;)&lt;br /&gt;ON COMMIT DELETE ROWS&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;drop table stage_proc_lock;&lt;br /&gt;create table stage_proc_lock&lt;br /&gt;(&lt;br /&gt;stage_table varchar2(30),&lt;br /&gt;part_key number(2)&lt;br /&gt;)&lt;br /&gt;tablespace index_auto;&lt;br /&gt;&lt;br /&gt;create index stage_proc_lock_i1 on stage_proc_lock(stage_table,part_key)&lt;br /&gt;nologging tablespace index_auto;&lt;br /&gt;&lt;br /&gt;DROP TABLE book_delete_stage_part;&lt;br /&gt;&lt;br /&gt;CREATE TABLE book_delete_stage_part (&lt;br /&gt;listingsid number(20),&lt;br /&gt;qty number(5),&lt;br /&gt;delete_flag number(1),&lt;br /&gt;update_date timestamp(3) default SysTimestamp,&lt;br /&gt;part_mi number(2) default mod(to_number(to_char(sysdate,'MI')),10)&lt;br /&gt;)&lt;br /&gt;PARTITION BY LIST (part_mi) (&lt;br /&gt;  PARTITION data_part_0 VALUES (0),&lt;br /&gt;  PARTITION data_part_1 VALUES (1),&lt;br /&gt;  PARTITION data_part_2 VALUES (2),&lt;br /&gt;  PARTITION data_part_3 VALUES (3),&lt;br /&gt;  PARTITION data_part_4 VALUES (4),&lt;br /&gt;  PARTITION data_part_5 VALUES (5),&lt;br /&gt;  PARTITION data_part_6 VALUES (6),&lt;br /&gt;  PARTITION data_part_7 VALUES (7),&lt;br /&gt;  PARTITION data_part_8 VALUES (8),&lt;br /&gt;  PARTITION data_part_9 VALUES (9),&lt;br /&gt;  PARTITION dummy_null  VALUES (NULL),&lt;br /&gt;  PARTITION dummy_other VALUES (DEFAULT)&lt;br /&gt;)&lt;br /&gt;tablespace data_auto;&lt;br /&gt;&lt;br /&gt;DROP TABLE book_delete_stage_swap_0;&lt;br /&gt;DROP TABLE book_delete_stage_swap_1;&lt;br /&gt;DROP TABLE book_delete_stage_swap_2;&lt;br /&gt;DROP TABLE book_delete_stage_swap_3;&lt;br /&gt;DROP TABLE book_delete_stage_swap_4;&lt;br /&gt;DROP TABLE book_delete_stage_swap_5;&lt;br /&gt;DROP TABLE book_delete_stage_swap_6;&lt;br /&gt;DROP TABLE book_delete_stage_swap_7;&lt;br /&gt;DROP TABLE book_delete_stage_swap_8;&lt;br /&gt;DROP TABLE book_delete_stage_swap_9;&lt;br /&gt;&lt;br /&gt;CREATE TABLE book_delete_stage_swap_0 (listingsid number(20),qty number(5),delete_flag number(1),update_date timestamp(3),part_mi number(2)) tablespace data_auto;&lt;br /&gt;CREATE TABLE book_delete_stage_swap_1 (listingsid number(20),qty number(5),delete_flag number(1),update_date timestamp(3),part_mi number(2)) tablespace data_auto;&lt;br /&gt;CREATE TABLE book_delete_stage_swap_2 (listingsid number(20),qty number(5),delete_flag number(1),update_date timestamp(3),part_mi number(2)) tablespace data_auto;&lt;br /&gt;CREATE TABLE book_delete_stage_swap_3 (listingsid number(20),qty number(5),delete_flag number(1),update_date timestamp(3),part_mi number(2)) tablespace data_auto;&lt;br /&gt;CREATE TABLE book_delete_stage_swap_4 (listingsid number(20),qty number(5),delete_flag number(1),update_date timestamp(3),part_mi number(2)) tablespace data_auto;&lt;br /&gt;CREATE TABLE book_delete_stage_swap_5 (listingsid number(20),qty number(5),delete_flag number(1),update_date timestamp(3),part_mi number(2)) tablespace data_auto;&lt;br /&gt;CREATE TABLE book_delete_stage_swap_6 (listingsid number(20),qty number(5),delete_flag number(1),update_date timestamp(3),part_mi number(2)) tablespace data_auto;&lt;br /&gt;CREATE TABLE book_delete_stage_swap_7 (listingsid number(20),qty number(5),delete_flag number(1),update_date timestamp(3),part_mi number(2)) tablespace data_auto;&lt;br /&gt;CREATE TABLE book_delete_stage_swap_8 (listingsid number(20),qty number(5),delete_flag number(1),update_date timestamp(3),part_mi number(2)) tablespace data_auto;&lt;br /&gt;CREATE TABLE book_delete_stage_swap_9 (listingsid number(20),qty number(5),delete_flag number(1),update_date timestamp(3),part_mi number(2)) tablespace data_auto;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- Package&lt;br /&gt;@BOOK_CHG_SYNC_PKG.SQL&lt;br /&gt;&lt;br /&gt;alter package book_chg_sync_pkg compile;&lt;br /&gt;-- to avoid ORA-4061&lt;br /&gt;alter package list_trigger_pkg compile;&lt;br /&gt;&lt;br /&gt;-- to avoid ORA-4061&lt;br /&gt;-- Synonym&lt;br /&gt;create or replace synonym BOOK_CHG_SYNC_api for BOOK_CHG_SYNC_PKG;&lt;br /&gt;&lt;br /&gt;grant execute on book_chg_sync_api to app_role;&lt;br /&gt;&lt;br /&gt;-- Schedule job&lt;br /&gt;exec dbms_scheduler.stop_job(job_name=&gt; 'merge_book_del_change_delta', force =&gt; True);&lt;br /&gt;exec dbms_scheduler.DROP_job ( job_name =&gt; 'merge_book_del_change_delta' );&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;   dbms_scheduler.create_job&lt;br /&gt;   (&lt;br /&gt;      job_name      =&gt; 'merge_book_del_change_delta',&lt;br /&gt;      job_type      =&gt; 'PLSQL_BLOCK',&lt;br /&gt;      job_action    =&gt; 'begin book_chg_sync_pkg.upd_delete_track; end;',&lt;br /&gt;      repeat_interval =&gt; 'FREQ=MINUTELY; INTERVAL=3',&lt;br /&gt;      enabled         =&gt; true,&lt;br /&gt;      comments        =&gt; 'To clear all the pending delta data, merge into book_del_check table'&lt;br /&gt;   );&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;Idea&lt;br /&gt;----&lt;br /&gt;-- Option n, online alter synonym pointer, no DDL lock, inconsistent data, unsafe&lt;br /&gt;drop table book_delete_stage;&lt;br /&gt;&lt;br /&gt;drop table book_delete_stage_t1;&lt;br /&gt;&lt;br /&gt;create table book_delete_stage_t1(&lt;br /&gt;listingsid number(20),&lt;br /&gt;qty number(5),&lt;br /&gt;delete_flag number(1),&lt;br /&gt;update_date date default sysdate&lt;br /&gt;)&lt;br /&gt;tablespace data_auto;&lt;br /&gt;&lt;br /&gt;create or replace synonym book_delete_stage for book_delete_stage_t1;&lt;br /&gt;&lt;br /&gt;drop table book_delete_stage_t2;&lt;br /&gt;&lt;br /&gt;create table book_delete_stage_t2(&lt;br /&gt;listingsid number(20),&lt;br /&gt;qty number(5),&lt;br /&gt;delete_flag number(1),&lt;br /&gt;update_date date default sysdate&lt;br /&gt;)&lt;br /&gt;tablespace data_auto;&lt;br /&gt;&lt;br /&gt;-- no DDL lock after DML done.&lt;br /&gt;insert into book_delete_stage&lt;br /&gt;values(1,1,1,sysdate);&lt;br /&gt;commit;&lt;br /&gt;&lt;br /&gt;create or replace synonym book_delete_stage for book_delete_stage_t2;&lt;br /&gt;&lt;br /&gt;select * from book_delete_stage_t1;&lt;br /&gt;select * from book_delete_stage_t2;&lt;br /&gt;select * from book_delete_stage;&lt;br /&gt;&lt;br /&gt;-- Option n+1, online exchange table partition&lt;br /&gt;-- for large TX volume&lt;br /&gt;-- Goal: Partition table to spread the contention&lt;br /&gt;&lt;br /&gt;*) Constraint : Must be run serially&lt;br /&gt;&lt;br /&gt;*) Process&lt;br /&gt;&lt;br /&gt;swap out the partitions Mod(minute,10) are not locked by DML &lt;br /&gt;insert into temporary table&lt;br /&gt;process&lt;br /&gt;commit&lt;br /&gt;truncate the swap table&lt;br /&gt;&lt;br /&gt;*) Test Case&lt;br /&gt;&lt;br /&gt;Insert 5 rows to each partition&lt;br /&gt;DML lock on 2 partitions&lt;br /&gt;exec book_chg_sync_pkg.merge_delta_multi_part;&lt;br /&gt;- Swap out other 8 partitions&lt;br /&gt;&lt;br /&gt;execute book_chg_sync_pkg.merge_delta_rowscn;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Test case&lt;br /&gt;---------&lt;br /&gt;*) Function&lt;br /&gt;&lt;br /&gt; - Delete some listings&lt;br /&gt; - Wait 5 minutes, run book_delete_check query, these listings should disappear.&lt;br /&gt;&lt;br /&gt; -) Restorea some listings&lt;br /&gt; -) Wait 5 minutes, run book_delete_check query, these listings should come out.&lt;br /&gt;&lt;br /&gt;*) Network performance - Test by Production DBA&lt;br /&gt;&lt;br /&gt;To check&lt;br /&gt;Global Cache and Enqueue Services - Workload Characteristics&lt;br /&gt; -Avg global enqueue get time (ms):     0.2&lt;br /&gt; -Avg global cache cr block receive time (ms):    3.7&lt;br /&gt; -Avg global cache current block receive time (ms):    2.5&lt;br /&gt; -Avg global cache cr block build time (ms):    0.0&lt;br /&gt; -Avg global cache cr block send time (ms):    0.1&lt;br /&gt; -Avg global cache current block pin time (ms): 0.0&lt;br /&gt; -Avg global cache current block send time (ms):0.1&lt;br /&gt;Global Cache and Enqueue Services - Messaging Statistics&lt;br /&gt; -Avg message sent queue time (ms):     50.8&lt;br /&gt; -Avg message sent queue time on ksxp (ms):    1.0&lt;br /&gt; -Avg message received queue time (ms): 0.0&lt;br /&gt;&lt;br /&gt;Test code&lt;br /&gt;---------&lt;br /&gt;&lt;br /&gt;-- Option n+1, online exchange table partition&lt;br /&gt;-- for large TX volume&lt;br /&gt;-- Goal: Partition table to spread the contention&lt;br /&gt;&lt;br /&gt;-- Test DELETE in MERGE.  (D.upd_dd &lt;&gt; S.upd_day or S.delete_flag = 0).&lt;br /&gt;insert into book_delete_stage_part(listingsid,qty,delete_flag,update_date, part_mi)&lt;br /&gt;values(7,5,0,trunc(sysdate,'DD') + 0, 4);&lt;br /&gt;&lt;br /&gt;insert into book_delete_stage_part(listingsid,qty,delete_flag,update_date, part_mi)&lt;br /&gt;values(7,5,0,trunc(sysdate,'DD') + 4, 4);&lt;br /&gt;commit;&lt;br /&gt;insert into book_delete_stage_part(listingsid,qty,delete_flag,update_date, part_mi)&lt;br /&gt;values(7,0,1,trunc(sysdate,'DD') + 4, 4);&lt;br /&gt;commit;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;select * from book_delete_stage_part;&lt;br /&gt;select * from book_delete_stage_swap_7;&lt;br /&gt;select * from book_del_check where listingsid = 7;&lt;br /&gt;&lt;br /&gt;SQL&gt; Exec book_chg_sync_pkg.merge_delta_multi_part;&lt;br /&gt;&lt;br /&gt;select * from book_delete_stage_part;&lt;br /&gt;select * from book_delete_stage_swap_7;&lt;br /&gt;select * from book_del_check where listingsid = 7;&lt;br /&gt;&lt;br /&gt;--Generate testing data&lt;br /&gt;insert into book_delete_stage_part(listingsid,delete_flag,update_date, part_mi)&lt;br /&gt;select trunc(dbms_random.value(1,5000)), mod(level,2), trunc(sysdate,'DD') + mod(level,60)/1440,&lt;br /&gt; mod(level,10)&lt;br /&gt;from dual&lt;br /&gt;connect by level &lt;= 7000;&lt;br /&gt;&lt;br /&gt;SQL&gt; Exec book_chg_sync_pkg.merge_delta_multi_part;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Reference&lt;br /&gt;---------&lt;br /&gt;&lt;br /&gt;-- Exchange partition&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--DDL With the WAIT Option, number of seconds, 11g new&lt;br /&gt;alter session set DDL_LOCK_TIMEOUT=120;&lt;br /&gt;&lt;br /&gt;-- ORA-00054: resource busy and acquire with NOWAIT specified&lt;br /&gt;ALTER TABLE book_delete_stage_part&lt;br /&gt;EXCHANGE PARTITION data_part_5&lt;br /&gt;WITH TABLE book_delete_stage_swap_5&lt;br /&gt;INCLUDING INDEXES&lt;br /&gt;WITHOUT VALIDATION&lt;br /&gt;UPDATE GLOBAL INDEXES&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;--DDL With the WAIT Option, number of seconds, 11g new&lt;br /&gt;alter session set DDL_LOCK_TIMEOUT=0;&lt;br /&gt;&lt;br /&gt;-- check TX view, 1000 LIO&lt;br /&gt;    SELECT to_char(t.start_date,'MI'), Min(t.start_date), count(*)&lt;br /&gt;    FROM   gv$transaction t&lt;br /&gt;          ,gv$locked_object lo&lt;br /&gt;--    FROM   v$transaction t&lt;br /&gt;--          ,v$locked_object lo&lt;br /&gt;            ,sys.obj$ do&lt;br /&gt;    WHERE  do.NAME   = 'BOOK_DELETE_STAGE'&lt;br /&gt;    AND    do.obj#   = lo.object_id&lt;br /&gt;    AND    lo.xidusn = t.xidusn&lt;br /&gt;group by to_char(t.start_date,'MI');&lt;br /&gt;&lt;br /&gt;-- Get partition number, skip locked partition&lt;br /&gt;-- check TX view, 1000 LIO&lt;br /&gt;   select Trim(to_char(part_num)) part_num bulk collect into lt_part_num from&lt;br /&gt;   (&lt;br /&gt;    select (level - 1) part_num from dual connect by level &lt;= 10&lt;br /&gt;    minus&lt;br /&gt;    SELECT Mod(to_number(to_char(t.start_date,'MI')),10) mi --, count(*)&lt;br /&gt;    FROM   gv$transaction t&lt;br /&gt;          ,gv$locked_object lo&lt;br /&gt;--    FROM   v$transaction t&lt;br /&gt;--          ,v$locked_object lo&lt;br /&gt;            ,sys.obj$ do&lt;br /&gt;    WHERE  do.NAME   = 'BOOK_DELETE_STAGE_PART'&lt;br /&gt;    AND    do.obj#   = lo.object_id&lt;br /&gt;    AND    lo.xidusn = t.xidusn&lt;br /&gt;    group by Mod(to_number(to_char(t.start_date,'MI')),10)&lt;br /&gt;   );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;*)AWR report RAC section anylysis&lt;br /&gt;&lt;br /&gt;15 minutes interval in the morning.&lt;br /&gt;&lt;br /&gt;The :F1 book_delete_check query used 90% network resource. Make all other database request that compete for network resource (Global cache transfer) worse and worse.&lt;br /&gt;Begin Snap: 13-Nov-08 10:45:20&lt;br /&gt;End Snap:   13-Nov-08 11:00:10&lt;br /&gt;&lt;br /&gt;Our practical target is to reduce the network usage 10 to 30 times by applying BASE solution.&lt;br /&gt;DBA can explain why in the story gathering meeting&lt;br /&gt;&lt;br /&gt; Network requests :&lt;br /&gt;= (CR Blocks Received + Current Blocks Received) + messages sent + messages received&lt;br /&gt;= (96884 + 12168 ) * 2&lt;br /&gt;= 218104&lt;br /&gt;&lt;br /&gt; Note: CR is consistent reads, Current is reads on current data block from disk&lt;br /&gt;&lt;br /&gt; Network band width:&lt;br /&gt;= Network requests * db_block_size&lt;br /&gt;= 218104 * 4096&lt;br /&gt;= 893,353,984 (Transfer about 900Mbytes in 15 minutes)&lt;br /&gt;&lt;br /&gt; Avg book_delete_check query wait time on network delay:&lt;br /&gt;= (  CR Blocks Received * Avg global cache cr block receive time ms&lt;br /&gt;   + Current Blocks Received * Avg global cache current block receive time ms&lt;br /&gt;   + Global Cache Grant messages * Avg message sent queue time ms&lt;br /&gt;  ) / Executions / 1000 ms&lt;br /&gt;= (96884 * 60.6 + 12168 * 72.8 + (96884 + 12168) * 201) /45211/1000&lt;br /&gt;= 0.634280436 Seconds&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-4036620500547277166?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/4036620500547277166/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=4036620500547277166' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/4036620500547277166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/4036620500547277166'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/01/overview-asynchronous-process-change.html' title='Overview asynchronous process change data'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Wv9Lui_cURQ/SW4922hEflI/AAAAAAAAAFQ/HxAOoRopgJo/s72-c/book_del_check.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-6927533898673014547</id><published>2009-01-12T14:50:00.000-08:00</published><updated>2009-01-13T14:37:46.760-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='generate'/><category scheme='http://www.blogger.com/atom/ns#' term='test'/><category scheme='http://www.blogger.com/atom/ns#' term='benchmark'/><title type='text'>How to generate testing data</title><content type='html'>Goal&lt;br /&gt;----&lt;br /&gt;Generate testing data&lt;br /&gt;&lt;br /&gt;Interpret&lt;br /&gt;---------&lt;br /&gt;Many times you need to build a test case to prove your ideas or prototype, benchmark, ask questions ... etc.&lt;br /&gt;&lt;br /&gt;Tom: You would better supply very very simple create tables and insert statements. &lt;br /&gt;The SMALLEST create table possible (no tablespaces, no schema names, just like I do in my examples for you) &lt;br /&gt;&lt;br /&gt;Solution&lt;br /&gt;--------&lt;br /&gt;&lt;br /&gt;*) 500 distinct value, to get centain data distribution&lt;br /&gt;&lt;br /&gt;Mod(rownum,500)&lt;br /&gt;dbms_random.value(1,500)&lt;br /&gt;dbms_random.normal()&lt;br /&gt;&lt;br /&gt;*) string&lt;br /&gt;&lt;br /&gt;rpad('x',500,'x')&lt;br /&gt;lpad(RowNum,200,'*')&lt;br /&gt;dbms_random.string('l',500)  &lt;br /&gt;# 'u', 'U' - returning string in uppercase alpha characters&lt;br /&gt;# 'l', 'L' - returning string in lowercase alpha characters&lt;br /&gt;# 'p': any printable char. this one is slow&lt;br /&gt;&lt;br /&gt;*) source&lt;br /&gt;&lt;br /&gt; # dual connect by level &lt;= 3000&lt;br /&gt; # all_objects&lt;br /&gt; # WITH subquery factor&lt;br /&gt;&lt;br /&gt;*) Random order by&lt;br /&gt;&lt;br /&gt;ORDER BY dbms_random.random;&lt;br /&gt;&lt;br /&gt;*) Example&lt;br /&gt;&lt;br /&gt;SQL&gt; &lt;br /&gt;--Resets the seed&lt;br /&gt;exec dbms_random.seed(1);&lt;br /&gt;&lt;br /&gt;drop table t1;&lt;br /&gt;create table t1 &lt;br /&gt;nologging  -- adjust as necessary&lt;br /&gt;as&lt;br /&gt;with g as (&lt;br /&gt; select -- materialize&lt;br /&gt;   level&lt;br /&gt; from dual &lt;br /&gt; connect by level &lt;= 2000&lt;br /&gt;)&lt;br /&gt;select&lt;br /&gt; /*x leading(v1,v2,v3) use_merge(v2) use_merge(v3) */&lt;br /&gt; /*+ leading(v1,v2,v3) use_nl(v2) use_nl(v3) */&lt;br /&gt; rownum id,&lt;br /&gt; Round(dbms_random.normal * 1000,3) n1,&lt;br /&gt; Mod(rownum,500) n5,&lt;br /&gt; Mod(rownum,400) n4,&lt;br /&gt; Round(dbms_random.value(1,700)) n7b&lt;br /&gt; ,rpad(rownum,500,'x') s5&lt;br /&gt;-- ,dbms_random.string('l',20) s5b&lt;br /&gt; ,Trunc(sysdate,'YYYY') + Mod(rownum,1440)/1440 update_date&lt;br /&gt;from&lt;br /&gt;  g v1&lt;br /&gt; ,g v2&lt;br /&gt; ,g v3&lt;br /&gt;where&lt;br /&gt; rownum &lt;= 111222&lt;br /&gt;-- order by dbms_random.random&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;create index t1_i1 on t1(n5) nologging ;&lt;br /&gt;&lt;br /&gt;exec dbms_stats.gather_table_stats(user,'T1');&lt;br /&gt;&lt;br /&gt;# MuJiang&lt;br /&gt;&lt;br /&gt;DROP TABLE abelisting.book_delete_stage_part;&lt;br /&gt;&lt;br /&gt;CREATE TABLE abelisting.book_delete_stage_part (&lt;br /&gt;listingsid number(20),&lt;br /&gt;qty number(5),&lt;br /&gt;delete_flag number(1),&lt;br /&gt;update_date timestamp(3) default SysTimestamp,&lt;br /&gt;part_mi number(2) default mod(to_number(to_char(sysdate,'MI')),10)&lt;br /&gt;)&lt;br /&gt;PARTITION BY LIST (part_mi) (&lt;br /&gt;  PARTITION data_part_0 VALUES (0),&lt;br /&gt;  PARTITION data_part_1 VALUES (1),&lt;br /&gt;  PARTITION data_part_2 VALUES (2),&lt;br /&gt;  PARTITION data_part_3 VALUES (3),&lt;br /&gt;  PARTITION data_part_4 VALUES (4),&lt;br /&gt;  PARTITION data_part_5 VALUES (5),&lt;br /&gt;  PARTITION data_part_6 VALUES (6),&lt;br /&gt;  PARTITION data_part_7 VALUES (7),&lt;br /&gt;  PARTITION data_part_8 VALUES (8),&lt;br /&gt;  PARTITION data_part_9 VALUES (9),&lt;br /&gt;  PARTITION dummy_null  VALUES (NULL),&lt;br /&gt;  PARTITION dummy_other VALUES (DEFAULT)&lt;br /&gt;)&lt;br /&gt;tablespace data_auto;&lt;br /&gt;&lt;br /&gt;-- 5000 distinct values, 2000 duplicate values&lt;br /&gt;insert into abelisting.book_delete_stage_part(listingsid,delete_flag,update_date, part_mi)&lt;br /&gt;select trunc(dbms_random.value(1,5000)), mod(level,2), trunc(sysdate,'DD') + mod(level,60)/1440,&lt;br /&gt; mod(level,10)&lt;br /&gt;from dual&lt;br /&gt;connect by level &lt;= 7000;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Reference&lt;br /&gt;---------&lt;br /&gt;&lt;br /&gt;# Christian Antognini&lt;br /&gt;drop table t;&lt;br /&gt;CREATE TABLE t&lt;br /&gt;AS&lt;br /&gt;SELECT rownum AS id,&lt;br /&gt;       round(5678+dbms_random.normal*1234) AS n1,&lt;br /&gt;       mod(255+trunc(dbms_random.normal*1000),255) AS n2,&lt;br /&gt;       dbms_random.string('p',255) AS pad&lt;br /&gt;FROM dual&lt;br /&gt;CONNECT BY level &lt;= 10000&lt;br /&gt;ORDER BY dbms_random.value;&lt;br /&gt;&lt;br /&gt;# Jonathan Lewis&lt;br /&gt;&lt;br /&gt;drop table t1;&lt;br /&gt;create table t1 &lt;br /&gt;nologging  -- adjust as necessary&lt;br /&gt;as&lt;br /&gt;with generator as (&lt;br /&gt; select --+ materialize&lt;br /&gt;  rownum     id,&lt;br /&gt; substr(dbms_random.string('U',4),1,4) sortcode&lt;br /&gt; from all_objects &lt;br /&gt; where rownum &lt;= 5000&lt;br /&gt;)&lt;br /&gt;select&lt;br /&gt; /*+ ordered use_nl(v2) */&lt;br /&gt; substr(v2.sortcode,1,4) || substr(v1.sortcode,1,2) sortcode,&lt;br /&gt; substr(v1.sortcode,2,2)     v2,&lt;br /&gt; substr(v2.sortcode,2,3)     v3&lt;br /&gt;from&lt;br /&gt; generator v1,&lt;br /&gt; generator v2&lt;br /&gt;where&lt;br /&gt; rownum &lt;= 1048576&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# Tanel Põder&lt;br /&gt;&lt;a href="http://blog.tanelpoder.com/2008/06/08/generating-lots-of-rows-using-connect-by-safely/ "&gt;Generating lots of rows using connect by - safely!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;select rownum r&lt;br /&gt;from&lt;br /&gt;        (select rownum r from dual connect by rownum &lt;= 1000) a,&lt;br /&gt;        (select rownum r from dual connect by rownum &lt;= 1000) b,&lt;br /&gt;        (select rownum r from dual connect by rownum &lt;= 1000) c&lt;br /&gt;where rownum &lt;= 100000000;&lt;br /&gt;&lt;br /&gt;AskTom&lt;br /&gt;&lt;br /&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:48704116042682"&gt;AskTom&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ops$tkyte@ORA9IR2&gt; &lt;br /&gt;&lt;br /&gt;CREATE TABLE t1&lt;br /&gt;(&lt;br /&gt;  dt  date,&lt;br /&gt;  x   int,&lt;br /&gt;  y   varchar2(25)&lt;br /&gt;)&lt;br /&gt;PARTITION BY RANGE (dt)&lt;br /&gt;subpartition by hash(x) subpartitions 8&lt;br /&gt;(&lt;br /&gt;  PARTITION part1 VALUES LESS THAN (to_date('13-mar-2003','dd-mon-yyyy')) ,&lt;br /&gt;  PARTITION part2 VALUES LESS THAN (to_date('14-mar-2003','dd-mon-yyyy')) ,&lt;br /&gt;  PARTITION junk VALUES LESS THAN (MAXVALUE)&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;insert /*+ APPEND */ into t1&lt;br /&gt;select to_date('12-mar-2003','dd-mon-yyyy')+mod(rownum,4), rownum, rpad('*',25,'*')&lt;br /&gt;from all_objects;&lt;br /&gt;&lt;br /&gt;drop table t;&lt;br /&gt;create table t as select * from all_objects;&lt;br /&gt;create index t_idx on t(object_name);&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-6927533898673014547?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/6927533898673014547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=6927533898673014547' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/6927533898673014547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/6927533898673014547'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/01/how-to-generate-testing-data.html' title='How to generate testing data'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-2940201924893713576</id><published>2009-01-08T21:58:00.000-08:00</published><updated>2009-04-08T14:29:12.539-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='consistency'/><category scheme='http://www.blogger.com/atom/ns#' term='asynchronous process'/><category scheme='http://www.blogger.com/atom/ns#' term='BASE'/><title type='text'>Why asynchronous process?</title><content type='html'>This article is major for traditional internal business data owners, product managers and programmers.&lt;br /&gt;&lt;br /&gt;&lt;ul  style="font-weight: bold;font-family:courier new;"&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;Then why we bother to consider asynchronous process?&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;# transactional growth, data storage and workload become bottleneck in one single system.&lt;br /&gt;# moving the application to larger computers. there are 2 main limitations:&lt;br /&gt;- outgrowing the capacity of the largest system available&lt;br /&gt;- expensive&lt;br /&gt;# Try distribution transparency(2PC) to insure consistency and accuracy.&lt;br /&gt;- it was better to fail the complete system than to break this transparency.&lt;br /&gt;# Three properties of shared-data systems—data Consistency, system Availability, and tolerance to network Partition—only two can be achieved at any given time.&lt;br /&gt;- Network partition is a given.&lt;br /&gt;- consistency and availability cannot be achieved at the same time.&lt;br /&gt;^ making consistency a priority means that under  certain conditions the system will &lt;span style="color: rgb(255, 0, 0);"&gt;not be available&lt;/span&gt;.&lt;br /&gt;^ &lt;span style="color: rgb(0, 153, 0);"&gt;relaxing consistency&lt;/span&gt; will allow the system to remain highly available under the partition network conditions.&lt;br /&gt;&lt;br /&gt;&lt;ul  style="font-weight: bold;font-family:courier new;"&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;Solution&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Focus on the trade-offs between high availability and data consistency and large-scale data replication through messaging system, batch process the staging data with transaction Database API, we can deliver durability, availability,performance and cost effectiveness large-scale distributed database systems and infrastructure services.&lt;br /&gt;&lt;br /&gt;BASE allows for availability in a partitioned database, then &lt;span style="font-weight: bold; color: rgb(51, 51, 255);"&gt;opportunities to relax consistency have to be identified&lt;/span&gt;. This is often difficult because the tendency of both business stakeholders and developers is to assert that consistency is &lt;span style="color: rgb(102, 102, 102); font-weight: bold;"&gt;paramount &lt;/span&gt;to the success of the application. Temporal inconsistency cannot be hidden from the end user, so &lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;both engineering and product owners must be involved&lt;/span&gt; in picking the opportunities for relaxing consistency.&lt;br /&gt;&lt;br /&gt;Practical example:&lt;br /&gt;&lt;br /&gt;Book qty, 2 input sources, it is not accurate in fact.&lt;br /&gt;- update sequence&lt;br /&gt;- priority&lt;br /&gt;- conflict resolution&lt;br /&gt;Consistency can be relaxed and use just don't care the consistency&lt;br /&gt;take advantage of user-perceived consistency window between write and read&lt;br /&gt;# Finance batch process&lt;br /&gt;# Orders and Credit card batch update&lt;br /&gt;# Return items batch process&lt;br /&gt;&lt;br /&gt;ACID: transfer money from one account to another account, maintain total amount same.&lt;br /&gt;&lt;br /&gt;The requirement ratio  of ACID vs. BASE is about 1:100, like 100 searches generate 1 order.&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;a: Flight ticket booking system&lt;br /&gt;b: 1% performance decrease caused 5% orders lost&lt;br /&gt;c: publish a new book and make it online for search&lt;br /&gt;d: user data, e.g. sale_amt, purchase_amt&lt;br /&gt;&lt;br /&gt;Reference:&lt;br /&gt;&lt;br /&gt;Good things come to who can wait.&lt;br /&gt;* &lt;a href="http://www.infoq.com/articles/ebay-scalability-best-practices"&gt;Scalability Best Practices: Lessons from eBay (Partition and Asynchronously) &lt;/a&gt;&lt;br /&gt;* &lt;a href="http://queue.acm.org/detail.cfm?id=1394128"&gt;BASE: AN ACID ALTERNATIVE&lt;/a&gt;&lt;br /&gt;* &lt;a href="http://www.allthingsdistributed.com/2008/12/eventually_consistent.html"&gt;Eventually Consistent&lt;/a&gt;&lt;br /&gt;* &lt;a href="http://highscalability.com/latency-everywhere-and-it-costs-you-sales-how-crush-it"&gt;Latency is Everywhere and it Costs You Sales - How to Crush it&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Wv9Lui_cURQ/SWbpShKazKI/AAAAAAAAAFA/5-9cwIkwYCg/s1600-h/office_seat01.JPG"&gt;&lt;img style="cursor: pointer; width: 400px; height: 267px;" src="http://1.bp.blogspot.com/_Wv9Lui_cURQ/SWbpShKazKI/AAAAAAAAAFA/5-9cwIkwYCg/s400/office_seat01.JPG" alt="" id="BLOGGER_PHOTO_ID_5289171316742212770" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;My cubicle in office.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-2940201924893713576?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/2940201924893713576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=2940201924893713576' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/2940201924893713576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/2940201924893713576'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/01/why-asynchronous-process.html' title='Why asynchronous process?'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Wv9Lui_cURQ/SWbpShKazKI/AAAAAAAAAFA/5-9cwIkwYCg/s72-c/office_seat01.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-8995198747152975858</id><published>2009-01-07T21:55:00.000-08:00</published><updated>2009-03-28T11:29:01.733-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Analytic'/><title type='text'>cross rows comparing</title><content type='html'>Goal&lt;br /&gt;----&lt;br /&gt;Try many approaches to do cross rows comparing.&lt;br /&gt;&lt;br /&gt;Solution&lt;br /&gt;--------&lt;br /&gt;1. Hash Join&lt;br /&gt;eagle’s home http://www.dbafan.com/blog/?p=176&lt;br /&gt;&lt;br /&gt;2. Lead()/Lag() Analytic function&lt;br /&gt;&lt;br /&gt;3. SQL Model&lt;br /&gt;&lt;br /&gt;Outcome&lt;br /&gt;-------&lt;br /&gt;Hash Join is a good option, Lead() Analytic function is better, less db time, 8 times less Latches.&lt;br /&gt;I could not make SQL Model work efficiently.&lt;br /&gt;For large data set, SQL Model asks much more PGA and temporary tablespace to do sort.&lt;br /&gt;Reduce the columns from Measure will help a little.&lt;br /&gt;&lt;br /&gt;Who can help to tune SQL Model?&lt;br /&gt;&lt;br /&gt;Setup&lt;br /&gt;-----&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;drop table scott.t_range ;&lt;br /&gt;create table scott.t_range nologging&lt;br /&gt;as&lt;br /&gt;select level id, level * 10 low_value, level * 10 + Trunc(dbms_random.value(1,11)) high_value&lt;br /&gt;from dual&lt;br /&gt;connect by level &lt;= 300000&lt;br /&gt;order by dbms_random.value;&lt;br /&gt;&lt;br /&gt;exec dbms_stats.gather_table_stats('SCOTT','T_RANGE');&lt;br /&gt;&lt;br /&gt;Notes: do not do it in production database.&lt;br /&gt;&lt;br /&gt;SQL code&lt;br /&gt;--------&lt;br /&gt;1. Hash Join&lt;br /&gt;&lt;br /&gt;drop table scott.t_range_tmp;&lt;br /&gt;create table scott.t_range_tmp nologging as&lt;br /&gt;select rownum line_no,low_value,high_value&lt;br /&gt;from&lt;br /&gt;(&lt;br /&gt;select low_value,high_value&lt;br /&gt;from scott.t_range &lt;br /&gt;order by low_value asc&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;select a.low_value,a.high_value,b.low_value,b.high_value&lt;br /&gt;from scott.t_range_tmp a,scott.t_range_tmp b&lt;br /&gt;where a.line_no=b.line_no - 1 and a.high_value&gt;=b.low_value;&lt;br /&gt;&lt;br /&gt;2. Lead()/Lag() Analytic function&lt;br /&gt;&lt;br /&gt;select * from&lt;br /&gt;(&lt;br /&gt;select id,low_value,high_value,&lt;br /&gt;Lead(low_value,1) OVER (ORDER BY low_value) next_low_value&lt;br /&gt;from scott.t_range&lt;br /&gt;)&lt;br /&gt;where next_low_value &lt;= high_value;&lt;br /&gt;&lt;br /&gt;3. SQL Model, slow, need tuning&lt;br /&gt;&lt;br /&gt;with a as (SELECT rownum line_no,low_value,high_value FROM scott.t_range order by low_value asc)&lt;br /&gt;select line_no,low_value,next_low_value&lt;br /&gt;FROM a&lt;br /&gt;MODEL&lt;br /&gt;  --RETURN UPDATED ROWS&lt;br /&gt;  MAIN simple_model&lt;br /&gt;  --PARTITION BY (country)&lt;br /&gt;  DIMENSION BY (line_no)&lt;br /&gt;  MEASURES (low_value,high_value, 0 AS next_low_value)&lt;br /&gt;  RULES&lt;br /&gt;   (next_low_value[ANY] = low_value[cv(line_no) + 1])&lt;br /&gt;)&lt;br /&gt;where next_low_value &lt;= high_value;&lt;br /&gt;&lt;br /&gt;Benchmark&lt;br /&gt;---------&lt;br /&gt;* RunStats&lt;br /&gt;&lt;br /&gt;SQL&gt; set arraysize 1000&lt;br /&gt;&lt;br /&gt;exec runStats_pkg.rs_start;&lt;br /&gt;&lt;br /&gt;drop table scott.t_range_tmp;&lt;br /&gt;create table scott.t_range_tmp nologging as&lt;br /&gt;select rownum line_no,low_value,high_value&lt;br /&gt;from&lt;br /&gt;(&lt;br /&gt;select low_value,high_value&lt;br /&gt;from scott.t_range &lt;br /&gt;order by low_value asc&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;select count(*) from (&lt;br /&gt;select a.low_value,a.high_value,b.low_value,b.high_value&lt;br /&gt;from scott.t_range_tmp a,scott.t_range_tmp b&lt;br /&gt;where a.line_no=b.line_no - 1 and a.high_value&gt;=b.low_value&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;exec runStats_pkg.rs_middle;&lt;br /&gt;&lt;br /&gt;select count(*) from&lt;br /&gt;(&lt;br /&gt;select * from&lt;br /&gt;(&lt;br /&gt;select id,low_value,high_value,&lt;br /&gt;Lead(low_value,1) OVER (ORDER BY low_value) next_low_value&lt;br /&gt;from scott.t_range&lt;br /&gt;)&lt;br /&gt;where next_low_value &lt;= high_value&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;exec runStats_pkg.rs_stop(20);&lt;br /&gt;&lt;br /&gt;Run1 ran in 270 hsecs&lt;br /&gt;Run2 ran in 201 hsecs&lt;br /&gt;run 1 ran in 134.33% of the run2 time&lt;br /&gt;&lt;br /&gt;Name                                     Run1           Run2           Diff&lt;br /&gt;LATCH.JS queue state obj latch             90             60            -30&lt;br /&gt;STAT...redo ordering marks                 33              1            -32&lt;br /&gt;STAT...CPU used when call star            209            177            -32&lt;br /&gt;STAT...workarea memory allocat            -32              0             32&lt;br /&gt;STAT...CPU used by this sessio            209            177            -32&lt;br /&gt;STAT...consistent changes                  82             47            -35&lt;br /&gt;LATCH.redo allocation                      39              0            -39&lt;br /&gt;LATCH.begin backup scn array               41              0            -41&lt;br /&gt;LATCH.child cursor hash table              45              0            -45&lt;br /&gt;LATCH.redo writing                         46              0            -46&lt;br /&gt;STAT...data blocks consistent              47              0            -47&lt;br /&gt;STAT...rollbacks only - consis             47              0            -47&lt;br /&gt;STAT...CR blocks created                   47              0            -47&lt;br /&gt;STAT...deferred (CURRENT) bloc             55              8            -47&lt;br /&gt;STAT...DB time                            225            177            -48&lt;br /&gt;STAT...cluster key scans                   51              0            -51&lt;br /&gt;STAT...commit cleanouts succes             67              0            -67&lt;br /&gt;STAT...Elapsed Time                       272            203            -69&lt;br /&gt;STAT...session cursor cache hi             79              4            -75&lt;br /&gt;LATCH.SQL memory manager worka             81              6            -75&lt;br /&gt;STAT...commit cleanouts                    75              0            -75&lt;br /&gt;STAT...index fetch by key                  76              0            -76&lt;br /&gt;LATCH.messages                             95             12            -83&lt;br /&gt;STAT...cluster key scan block              99              0            -99&lt;br /&gt;STAT...calls to kcmgas                    111              1           -110&lt;br /&gt;STAT...opened cursors cumulati            121              4           -117&lt;br /&gt;LATCH.checkpoint queue latch              118              0           -118&lt;br /&gt;STAT...parse count (total)                123              4           -119&lt;br /&gt;STAT...physical write IO reque            126              0           -126&lt;br /&gt;STAT...execute count                      131              5           -126&lt;br /&gt;LATCH.dml lock allocation                 130              0           -130&lt;br /&gt;LATCH.cache buffers lru chain             140              0           -140&lt;br /&gt;STAT...enqueue requests                   157              1           -156&lt;br /&gt;STAT...enqueue releases                   158              0           -158&lt;br /&gt;STAT...consistent gets - exami            245             12           -233&lt;br /&gt;STAT...physical read IO reques            238              0           -238&lt;br /&gt;LATCH.undo global data                    274             14           -260&lt;br /&gt;LATCH.library cache lock                  263              0           -263&lt;br /&gt;LATCH.multiblock read objects             282              0           -282&lt;br /&gt;LATCH.enqueues                            411            128           -283&lt;br /&gt;STAT...buffer is not pinned co            305              0           -305&lt;br /&gt;STAT...calls to get snapshot s            318              9           -309&lt;br /&gt;STAT...bytes sent via SQL*Net           1,098            662           -436&lt;br /&gt;LATCH.enqueue hash chains                 609            130           -479&lt;br /&gt;STAT...redo entries                       568             19           -549&lt;br /&gt;LATCH.shared pool                         696             38           -658&lt;br /&gt;STAT...db block changes                   817             68           -749&lt;br /&gt;LATCH.library cache pin                   817             50           -767&lt;br /&gt;STAT...db block gets from cach            944             43           -901&lt;br /&gt;LATCH.simulator hash latch                978              1           -977&lt;br /&gt;STAT...bytes received via SQL*          2,070          1,058         -1,012&lt;br /&gt;LATCH.library cache                     1,155             62         -1,093&lt;br /&gt;STAT...physical reads direct t          1,275              0         -1,275&lt;br /&gt;STAT...physical writes direct           1,275              0         -1,275&lt;br /&gt;STAT...physical reads direct            1,275              0         -1,275&lt;br /&gt;STAT...recursive calls                  1,509              1         -1,508&lt;br /&gt;LATCH.row cache objects                 1,535             18         -1,517&lt;br /&gt;STAT...physical reads cache pr          1,640              0         -1,640&lt;br /&gt;STAT...db block gets direct             1,793              0         -1,793&lt;br /&gt;STAT...physical reads cache             1,793              0         -1,793&lt;br /&gt;STAT...free buffer requested            1,894              1         -1,893&lt;br /&gt;LATCH.session allocation                2,030              0         -2,030&lt;br /&gt;STAT...db block gets                    2,737             43         -2,694&lt;br /&gt;STAT...physical reads                   3,068              0         -3,068&lt;br /&gt;STAT...physical writes                  3,068              0         -3,068&lt;br /&gt;STAT...physical writes direct           3,068              0         -3,068&lt;br /&gt;STAT...physical writes non che          3,068              0         -3,068&lt;br /&gt;STAT...table scan blocks gotte          5,605          1,795         -3,810&lt;br /&gt;STAT...no work - consistent re          5,663          1,795         -3,868&lt;br /&gt;STAT...consistent gets                  6,147          1,824         -4,323&lt;br /&gt;STAT...consistent gets from ca          6,147          1,824         -4,323&lt;br /&gt;LATCH.object queue header oper          5,777              2         -5,775&lt;br /&gt;STAT...session logical reads            8,884          1,867         -7,017&lt;br /&gt;LATCH.cache buffers chains             22,633          3,872        -18,761&lt;br /&gt;STAT...sorts (rows)                   322,072        302,880        -19,192&lt;br /&gt;STAT...undo change vector size         28,368          3,372        -24,996&lt;br /&gt;STAT...session pga memory             -65,536              0         65,536&lt;br /&gt;STAT...redo size                      100,132          4,880        -95,252&lt;br /&gt;STAT...table scan rows gotten         930,309        300,000       -630,309&lt;br /&gt;&lt;br /&gt;Run1 latches total versus Run2 -- difference and pct&lt;br /&gt;Run1           Run2           Diff       Pct&lt;br /&gt;38,553          4,446        -34,107    867.14%&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;exec runStats_pkg.rs_start;&lt;br /&gt;select count(*) from&lt;br /&gt;(&lt;br /&gt;with a as (SELECT rownum line_no,low_value,high_value FROM scott.t_range order by low_value asc)&lt;br /&gt;select line_no,low_value,next_low_value&lt;br /&gt;FROM a&lt;br /&gt;MODEL&lt;br /&gt;  --RETURN UPDATED ROWS&lt;br /&gt;  MAIN simple_model&lt;br /&gt;  --PARTITION BY (country)&lt;br /&gt;  DIMENSION BY (line_no)&lt;br /&gt;  MEASURES (low_value,high_value, 0 AS next_low_value)&lt;br /&gt;  RULES&lt;br /&gt;   (next_low_value[ANY] = low_value[cv(line_no) + 1])&lt;br /&gt;)&lt;br /&gt;where next_low_value &lt;= high_value&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;exec runStats_pkg.rs_middle;&lt;br /&gt;select count(*) from&lt;br /&gt;(&lt;br /&gt;select * from&lt;br /&gt;(&lt;br /&gt;select id,low_value,high_value,&lt;br /&gt;Lead(low_value,1) OVER (ORDER BY low_value) next_low_value&lt;br /&gt;from scott.t_range&lt;br /&gt;)&lt;br /&gt;where next_low_value &lt;= high_value&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;exec runStats_pkg.rs_stop(20);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Reference&lt;br /&gt;---------&lt;br /&gt;Oracle® Database Data Warehousing Guide&lt;br /&gt;11g Release 1 (11.1)&lt;br /&gt;Part Number B28313-02&lt;br /&gt;&lt;br /&gt;21 SQL for Analysis and Reporting&lt;br /&gt;22 SQL for Modeling&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-8995198747152975858?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/8995198747152975858/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=8995198747152975858' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/8995198747152975858'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/8995198747152975858'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/01/cross-rows-comparing.html' title='cross rows comparing'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-4913712525114800181</id><published>2009-01-06T20:55:00.000-08:00</published><updated>2009-04-01T10:46:24.321-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='collection'/><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='ADT'/><title type='text'>3 PL/SQL approaches fetch data into ADT collection</title><content type='html'>Goal&lt;br /&gt;----&lt;br /&gt;There are 3 approaches to fetch data into schema object collection type.&lt;br /&gt;Benchmark to find the best one.&lt;br /&gt;&lt;br /&gt;Solution&lt;br /&gt;--------&lt;br /&gt;Setup test case, benchmark with RunStats and SQL trace.&lt;br /&gt;&lt;br /&gt;Result&lt;br /&gt;------&lt;br /&gt;PL/SQL native collection(Associative Array and Nested Table) is the fastest way to get data from SQL.&lt;br /&gt;But some time you need to query against a Collection/Array, you have to declare it as an schema object type.&lt;br /&gt;&lt;br /&gt;To fetch data into schema object type collection, here list 3 approaches Pros and Cons:&lt;br /&gt;&lt;br /&gt;1) Convert multi columns to object type, bulk collect into collection&lt;br /&gt;Pros: code is simple.&lt;br /&gt;Cons: 50% more CPU time compare to approach 2; about same amount of latches.&lt;br /&gt;&lt;br /&gt;2) Use multiset, constructs the required collection of ADTs directly in SQL as a select list element in a single row&lt;br /&gt;Pros: Faster, 50% better than approach 1 in my test case.&lt;br /&gt;Cons: code is a little complex, not support SQL Returning clause in 10.1.&lt;br /&gt;&lt;br /&gt;3) bulk collect into PL/SQL native collection, copy data into object type collection&lt;br /&gt;Pros: Fastest, 67% better than approach 1 in my test case, 50% less latches.&lt;br /&gt;Cons: use 100% more PGA memory, code is a little complex and not easy to maintain.&lt;br /&gt;&lt;br /&gt;Note: ADT: Abstract Data Type, also calls User Define Datatype&lt;br /&gt;&lt;br /&gt;Setup&lt;br /&gt;-----&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;drop TYPE abelisting.book_chg_tab;&lt;br /&gt;drop TYPE abelisting.book_chg_rec;&lt;br /&gt;&lt;br /&gt;create or replace TYPE abelisting.book_chg_rec  AS OBJECT&lt;br /&gt;(&lt;br /&gt;listingsid number(20),&lt;br /&gt;qty number(5),&lt;br /&gt;delete_flag number(1),&lt;br /&gt;update_date date&lt;br /&gt;);&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;create or replace TYPE abelisting.book_chg_tab IS TABLE OF abelisting.book_chg_rec;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;DROP TABLE abelisting.book_delete_stage_part;&lt;br /&gt;&lt;br /&gt;CREATE TABLE abelisting.book_delete_stage_part (&lt;br /&gt;listingsid number(20),&lt;br /&gt;qty number(5),&lt;br /&gt;delete_flag number(1),&lt;br /&gt;update_date timestamp(3) default SysTimestamp,&lt;br /&gt;part_mi number(2) default mod(to_number(to_char(sysdate,'MI')),10)&lt;br /&gt;)&lt;br /&gt;PARTITION BY LIST (part_mi) (&lt;br /&gt;  PARTITION data_part_0 VALUES (0),&lt;br /&gt;  PARTITION data_part_1 VALUES (1),&lt;br /&gt;  PARTITION data_part_2 VALUES (2),&lt;br /&gt;  PARTITION data_part_3 VALUES (3),&lt;br /&gt;  PARTITION data_part_4 VALUES (4),&lt;br /&gt;  PARTITION data_part_5 VALUES (5),&lt;br /&gt;  PARTITION data_part_6 VALUES (6),&lt;br /&gt;  PARTITION data_part_7 VALUES (7),&lt;br /&gt;  PARTITION data_part_8 VALUES (8),&lt;br /&gt;  PARTITION data_part_9 VALUES (9),&lt;br /&gt;  PARTITION dummy_null  VALUES (NULL),&lt;br /&gt;  PARTITION dummy_other VALUES (DEFAULT)&lt;br /&gt;)&lt;br /&gt;tablespace data_auto&lt;br /&gt;nologging;&lt;br /&gt;&lt;br /&gt;insert into /*+ append */ abelisting.book_delete_stage_part(listingsid,delete_flag,update_date, part_mi)&lt;br /&gt;select trunc(dbms_random.value(1,20000)), mod(level,2), trunc(sysdate,'DD') + mod(level,60)/1440,&lt;br /&gt; mod(level,10)&lt;br /&gt;from dual&lt;br /&gt;connect by level &lt;= 30000;&lt;br /&gt;commit;&lt;br /&gt;&lt;br /&gt;exec dbms_stats.gather_table_stats(user,'BOOK_DELETE_STAGE_PART');&lt;br /&gt;&lt;br /&gt;Code&lt;br /&gt;----&lt;br /&gt;&lt;br /&gt;*) RunStats&lt;br /&gt;&lt;br /&gt; # multiset vs. bulk collect into object_array&lt;br /&gt;&lt;br /&gt;declare&lt;br /&gt;   lt_chg abelisting.book_chg_tab; &lt;br /&gt;--   type my_book_chg_tab is table of abelisting.book_delete_stage%ROWTYPE;&lt;br /&gt;--   lt_chg my_book_chg_tab;&lt;br /&gt;   type tab_chg_array is table of abelisting.book_delete_stage_part%rowtype;&lt;br /&gt;   lt_chg_array tab_chg_array;&lt;br /&gt;begin&lt;br /&gt; runStats_pkg.rs_start;&lt;br /&gt;select cast(multiset(&lt;br /&gt;select book_chg_rec(LISTINGSID, QTY, DELETE_FLAG, UPDATE_DATE) from abelisting.book_delete_stage_part&lt;br /&gt;) as book_chg_tab)&lt;br /&gt;into lt_chg &lt;br /&gt;from dual;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;declare&lt;br /&gt;   lt_chg abelisting.book_chg_tab; &lt;br /&gt;   type item_chg_array is table of abelisting.book_delete_stage_part%rowtype;&lt;br /&gt;   lt_chg_array item_chg_array;&lt;br /&gt;begin&lt;br /&gt; runStats_pkg.rs_middle;&lt;br /&gt;select book_chg_rec(LISTINGSID, QTY, DELETE_FLAG, UPDATE_DATE)&lt;br /&gt;bulk collect into lt_chg&lt;br /&gt;from abelisting.book_delete_stage_part&lt;br /&gt;;&lt;br /&gt; runStats_pkg.rs_stop(5);&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;Run1 ran in 24 hsecs&lt;br /&gt;Run2 ran in 32 hsecs&lt;br /&gt;run 1 ran in 75% of the time&lt;br /&gt;&lt;br /&gt;Name                                  Run1        Run2        Diff&lt;br /&gt;STAT...recursive calls                  11           4          -7&lt;br /&gt;LATCH.active service list                0           7           7&lt;br /&gt;LATCH.cache buffers chains             909         902          -7&lt;br /&gt;LATCH.session idle bit                   8           0          -8&lt;br /&gt;STAT...Elapsed Time                     26          35           9&lt;br /&gt;STAT...recursive cpu usage              23          34          11&lt;br /&gt;STAT...db block gets                    63          51         -12&lt;br /&gt;STAT...db block gets from cach          63          51         -12&lt;br /&gt;STAT...session logical reads           390         377         -13&lt;br /&gt;STAT...workarea memory allocat         -34          -9          25&lt;br /&gt;STAT...CPU used when call star          28           0         -28&lt;br /&gt;STAT...CPU used by this sessio          28           0         -28&lt;br /&gt;STAT...DB time                          28           0         -28&lt;br /&gt;LATCH.library cache lock                41          12         -29&lt;br /&gt;LATCH.JS queue state obj latch           0          30          30&lt;br /&gt;LATCH.library cache pin                 64          24         -40&lt;br /&gt;LATCH.row cache objects                 69          27         -42&lt;br /&gt;LATCH.shared pool                       58          15         -43&lt;br /&gt;LATCH.enqueues                           8          68          60&lt;br /&gt;LATCH.enqueue hash chains                6          69          63&lt;br /&gt;LATCH.library cache                    130          36         -94&lt;br /&gt;STAT...undo change vector size       2,808       2,908         100&lt;br /&gt;STAT...redo size                     3,956       4,064         108&lt;br /&gt;LATCH.simulator hash latch               2         131         129&lt;br /&gt;STAT...bytes sent via SQL*Net          218           0        -218&lt;br /&gt;STAT...bytes received via SQL*         760           0        -760&lt;br /&gt;STAT...buffer is pinned count       29,796           0     -29,796&lt;br /&gt;STAT...session uga memory max      196,500           0    -196,500&lt;br /&gt;STAT...session pga memory max    6,815,744     393,216  -6,422,528&lt;br /&gt;STAT...session pga memory                0   7,208,960   7,208,960&lt;br /&gt;&lt;br /&gt;Run1 latches total versus runs -- difference and pct&lt;br /&gt;Run1        Run2        Diff       Pct&lt;br /&gt;1,337       1,356          19     98.60%&lt;br /&gt;&lt;br /&gt; # multiset vs. plsql_collection copy to object array&lt;br /&gt; &lt;br /&gt;declare&lt;br /&gt;   lt_chg abelisting.book_chg_tab; &lt;br /&gt;   type tab_chg_array is table of abelisting.book_delete_stage_part%rowtype;&lt;br /&gt;   lt_chg_array tab_chg_array;&lt;br /&gt;begin&lt;br /&gt; runStats_pkg.rs_start;&lt;br /&gt;select cast(multiset(&lt;br /&gt;select book_chg_rec(LISTINGSID, QTY, DELETE_FLAG, UPDATE_DATE) from abelisting.book_delete_stage_part&lt;br /&gt;) as book_chg_tab)&lt;br /&gt;into lt_chg &lt;br /&gt;from dual;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;declare&lt;br /&gt;   lt_chg abelisting.book_chg_tab; &lt;br /&gt;   type item_chg_array is table of abelisting.book_delete_stage_part%rowtype;&lt;br /&gt;   lt_chg_array item_chg_array;&lt;br /&gt;begin&lt;br /&gt; runStats_pkg.rs_middle;&lt;br /&gt;&lt;br /&gt;select LISTINGSID, QTY, DELETE_FLAG, UPDATE_DATE, Null&lt;br /&gt;bulk collect into lt_chg_array&lt;br /&gt;from abelisting.book_delete_stage_part;&lt;br /&gt;&lt;br /&gt; lt_chg := abelisting.book_chg_tab();&lt;br /&gt; lt_chg.extend(lt_chg_array.count());&lt;br /&gt; For i in lt_chg_array.First() .. lt_chg_array.Last()&lt;br /&gt; Loop&lt;br /&gt;   lt_chg(i)  := book_chg_rec(lt_chg_array(i).LISTINGSID,&lt;br /&gt;    lt_chg_array(i).QTY  ,&lt;br /&gt;    lt_chg_array(i).DELETE_FLAG,&lt;br /&gt;    lt_chg_array(i).UPDATE_DATE&lt;br /&gt;   );&lt;br /&gt; End Loop;&lt;br /&gt; runStats_pkg.rs_stop(5);&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;Run1 ran in 27 hsecs&lt;br /&gt;Run2 ran in 17 hsecs&lt;br /&gt;run 1 ran in 158.82% of the time&lt;br /&gt;&lt;br /&gt;Name                                  Run1        Run2        Diff&lt;br /&gt;STAT...opened cursors cumulati           8           2          -6&lt;br /&gt;LATCH.active service list                0           7           7&lt;br /&gt;LATCH.child cursor hash table            7           0          -7&lt;br /&gt;STAT...recursive calls                  12           4          -8&lt;br /&gt;LATCH.session idle bit                   8           0          -8&lt;br /&gt;STAT...Elapsed Time                     29          20          -9&lt;br /&gt;STAT...db block gets                    63          53         -10&lt;br /&gt;STAT...db block gets from cach          63          53         -10&lt;br /&gt;STAT...recursive cpu usage              23          12         -11&lt;br /&gt;STAT...workarea memory allocat          12          -7         -19&lt;br /&gt;STAT...calls to get snapshot s          62          38         -24&lt;br /&gt;STAT...table fetch by rowid             24           0         -24&lt;br /&gt;STAT...index fetch by key               24           0         -24&lt;br /&gt;LATCH.checkpoint queue latch             8          32          24&lt;br /&gt;STAT...rows fetched via callba          24           0         -24&lt;br /&gt;STAT...CPU used when call star          28           0         -28&lt;br /&gt;STAT...DB time                          28           0         -28&lt;br /&gt;STAT...CPU used by this sessio          28           0         -28&lt;br /&gt;LATCH.JS queue state obj latch           0          30          30&lt;br /&gt;STAT...free buffer inspected             0          38          38&lt;br /&gt;STAT...hot buffers moved to he           0          48          48&lt;br /&gt;STAT...buffer is not pinned co          48           0         -48&lt;br /&gt;LATCH.enqueues                          10          70          60&lt;br /&gt;LATCH.enqueue hash chains                8          71          63&lt;br /&gt;LATCH.SQL memory manager worka           4          71          67&lt;br /&gt;STAT...consistent gets                 397         327         -70&lt;br /&gt;LATCH.cache buffers chains             973         903         -70&lt;br /&gt;STAT...consistent gets from ca         397         327         -70&lt;br /&gt;STAT...consistent gets - exami          72           1         -71&lt;br /&gt;STAT...session logical reads           460         380         -80&lt;br /&gt;STAT...undo change vector size       2,804       2,904         100&lt;br /&gt;LATCH.simulator hash latch             130           3        -127&lt;br /&gt;STAT...redo size                     3,952       4,120         168&lt;br /&gt;LATCH.row cache objects                193          18        -175&lt;br /&gt;STAT...bytes sent via SQL*Net          218           0        -218&lt;br /&gt;LATCH.library cache lock               234          12        -222&lt;br /&gt;LATCH.library cache pin                256          25        -231&lt;br /&gt;LATCH.shared pool                      258          13        -245&lt;br /&gt;LATCH.library cache                    559          39        -520&lt;br /&gt;STAT...bytes received via SQL*       1,067           0      -1,067&lt;br /&gt;STAT...buffer is pinned count       29,796           0     -29,796&lt;br /&gt;STAT...session uga memory           65,464           0     -65,464&lt;br /&gt;STAT...session uga memory max      193,032      68,932    -124,100&lt;br /&gt;STAT...session pga memory max    6,815,744   9,895,936   3,080,192&lt;br /&gt;STAT...session pga memory           65,536  16,646,144  16,580,608&lt;br /&gt;&lt;br /&gt;Run1 latches total versus runs -- difference and pct&lt;br /&gt;Run1        Run2        Diff       Pct&lt;br /&gt;2,691       1,330      -1,361    202.33%&lt;br /&gt;&lt;br /&gt;*) SQL Trace&lt;br /&gt;&lt;br /&gt;ALTER SESSION SET TRACEFILE_IDENTIFIER="yi";&lt;br /&gt;EXECUTE DBMS_MONITOR.SESSION_TRACE_ENABLE(waits =&gt; TRUE, binds =&gt; True);&lt;br /&gt;&lt;br /&gt;declare&lt;br /&gt;   lt_chg abelisting.book_chg_tab; &lt;br /&gt;begin&lt;br /&gt;select cast(multiset(&lt;br /&gt;select book_chg_rec(LISTINGSID, QTY, DELETE_FLAG, UPDATE_DATE) from abelisting.book_delete_stage_part&lt;br /&gt;) as book_chg_tab)&lt;br /&gt;into lt_chg &lt;br /&gt;from dual;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;declare&lt;br /&gt;   lt_chg abelisting.book_chg_tab; &lt;br /&gt;begin&lt;br /&gt;select book_chg_rec(LISTINGSID, QTY, DELETE_FLAG, UPDATE_DATE)&lt;br /&gt;bulk collect into lt_chg &lt;br /&gt;from abelisting.book_delete_stage_part&lt;br /&gt;;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;EXECUTE DBMS_MONITOR.SESSION_TRACE_DISABLE();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;tkprof report&lt;br /&gt;-------------&lt;br /&gt;SELECT book_chg_rec(LISTINGSID, QTY, DELETE_FLAG, UPDATE_DATE)&lt;br /&gt;FROM&lt;br /&gt; ABELISTING.BOOK_DELETE_STAGE_PART&lt;br /&gt;&lt;br /&gt;call     count       cpu    elapsed       disk      query    current        rows&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;Parse        1      0.00       0.00          0          0          0           0&lt;br /&gt;Execute      1      0.00       0.00          0          0          0           0&lt;br /&gt;Fetch        1      0.34       0.33          0        316          0       30000&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;total        3      0.34       0.33          0        316          0       30000&lt;br /&gt;&lt;br /&gt;SELECT CAST(MULTISET( SELECT book_chg_rec(LISTINGSID, QTY, DELETE_FLAG,&lt;br /&gt;  UPDATE_DATE)&lt;br /&gt;FROM&lt;br /&gt; ABELISTING.BOOK_DELETE_STAGE_PART ) AS BOOK_CHG_TAB) FROM DUAL&lt;br /&gt;&lt;br /&gt;call     count       cpu    elapsed       disk      query    current        rows&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;Parse        1      0.00       0.00          0          0          0           0&lt;br /&gt;Execute      1      0.00       0.00          0          0          0           0&lt;br /&gt;Fetch        1      0.21       0.22          0        316          0           1&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;total        3      0.21       0.22          0        316          0           1&lt;br /&gt;&lt;br /&gt;Misses in library cache during parse: 0&lt;br /&gt;Optimizer mode: FIRST_ROWS&lt;br /&gt;Parsing user id: 35     (recursive depth: 1)&lt;br /&gt;&lt;br /&gt;Rows     Row Source Operation&lt;br /&gt;-------  ---------------------------------------------------&lt;br /&gt;      1  FAST DUAL  (cr=0 pr=0 pw=0 time=9 us)&lt;br /&gt;&lt;br /&gt;SELECT LISTINGSID, QTY, DELETE_FLAG, UPDATE_DATE, NULL&lt;br /&gt;FROM&lt;br /&gt; ABELISTING.BOOK_DELETE_STAGE_PART&lt;br /&gt;&lt;br /&gt;call     count       cpu    elapsed       disk      query    current        rows&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;Parse        1      0.00       0.00          0          0          0           0&lt;br /&gt;Execute      1      0.00       0.00          0          0          0           0&lt;br /&gt;Fetch        1      0.11       0.10          0        316          0       30000&lt;br /&gt;------- ------  -------- ---------- ---------- ---------- ----------  ----------&lt;br /&gt;total        3      0.11       0.10          0        316          0       30000&lt;br /&gt;&lt;br /&gt;Misses in library cache during parse: 1&lt;br /&gt;Optimizer mode: FIRST_ROWS&lt;br /&gt;Parsing user id: 35     (recursive depth: 1)&lt;br /&gt;&lt;br /&gt;Rows     Row Source Operation&lt;br /&gt;-------  ---------------------------------------------------&lt;br /&gt;  30000  PARTITION LIST ALL PARTITION: 1 12 (cr=316 pr=0 pw=0 time=90091 us)&lt;br /&gt;  30000   TABLE ACCESS FULL BOOK_DELETE_STAGE_PART PARTITION: 1 12 (cr=316 pr=0 pw=0 time=30379 us)&lt;br /&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-4913712525114800181?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/4913712525114800181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=4913712525114800181' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/4913712525114800181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/4913712525114800181'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2009/01/3-plsql-approaches-fetch-data-into-adt.html' title='3 PL/SQL approaches fetch data into ADT collection'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-4922547015258768075</id><published>2007-09-10T12:04:00.000-07:00</published><updated>2007-09-10T12:05:44.335-07:00</updated><title type='text'>Good practice: Middle-tier DAL or Database API – Database access guideline</title><content type='html'>The reason I don't use "Best Practice" is that will prevent rest of people create some better new ideas, and let you out the 'Keep an open mind' zone.&lt;br /&gt;&lt;br /&gt;So I turned to Good practice:&lt;br /&gt;&lt;br /&gt;Middle-tier DAL or Database API – Database access guideline&lt;br /&gt;&lt;strong&gt;(Hibernate vs Store procedure)&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;• Maximise SQL and minimise PL/SQL &lt;br /&gt;• Minimise client code and maximise database server code. &lt;br /&gt;&lt;br /&gt;Generally servers are more powerful and built for this type of work. You also want to minimise trips back and forth to the server.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Reference:&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Business Logic - PL/SQL Vs Java&lt;br /&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:883929178230"&gt;http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:883929178230&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I prefer to put all logic that deals with data in PLSQL.  There is no more natural language to interact with SQL data then PLSQL.  None.&lt;br /&gt;&lt;br /&gt;For example -- native compilation was added -- turned plsql into object code that runs natively on the OS.&lt;br /&gt;&lt;br /&gt;Database API, build the data API in the database, you call the data API&lt;br /&gt;&lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:25405782527721"&gt;http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:25405782527721&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;When to use Hibernate DAL&lt;/strong&gt;&lt;br /&gt;• One step SQL (SELECT OR UPDATE) to finish your goal &lt;br /&gt;• Heavy and forced interaction in mid tier, like CCBB encryption, that means high coulping too, and hard to encapsulate the process logic. &lt;br /&gt;&lt;br /&gt;Jave developer can help us on this list.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;When to use Database API and Store Procedure Package&lt;/strong&gt;&lt;br /&gt;• Complex SQL&lt;br /&gt;For example, book delete check, reference Single Hash Table and list of IDs. &lt;br /&gt;• Many (more than 2) steps data machinations logic in a sigle module &lt;br /&gt;• Reture rows more than one page, let's say 20 rows from database. &lt;br /&gt;&lt;br /&gt;We like Database API approach, because it:&lt;br /&gt;1.. make software components modular, I'm totally into modular programming &lt;br /&gt;2.. software modules must carry out a very specific task (and be very efficient at carrying it out) &lt;br /&gt;3.. each software module should be loosly coupled (to limit dependencies) &lt;br /&gt;4.. It removes the need for triggers as all inserts, updates and deletes are wrapped in APIs. Instead of writing triggers you simply add the code into the API. I loath triggers. &lt;br /&gt;5.. It prevents people who don't understand SQL writing stupid queries.&lt;br /&gt;All SQL would be written by PL/SQL developers or DBAs, reducing the likelyhood of dodgy queries. &lt;br /&gt;6.. The underlying structure of the database is hidden from the users, so I can make structural changes without client applications being changed.The API implementation can be altered and tuned without affecting the client application. &lt;br /&gt;7.. The same APIs are available to all applications that access the database. No duplication of effort.&lt;br /&gt;&lt;br /&gt;Anything that generates SQL on-the-fly worries me, not just Java. I want to be able to cut and paste the SQL, not try and capture or trace it during a run. &lt;br /&gt;&lt;br /&gt;Our concept is "build the data API in the database, you call the data API" .&lt;br /&gt;Database API has been layered by different UI technologies over time.&lt;br /&gt;&lt;br /&gt;All about API's. The applications don't do table level(select/insert/update/delete) stuff, the apps don't even really know about tables.&lt;br /&gt;&lt;br /&gt;On top of database schema we have an API that does the data stuff.&lt;br /&gt;&lt;br /&gt;In the application we call this API but have our own application logic as well&lt;br /&gt;(only application logic is in the application, data logic is – well, right where it belongs – next to the data, waiting for the 'next great programming paradigm to come along')&lt;br /&gt;&lt;br /&gt;The fact that our UI is in Java isn't really relevant. You could pretty much see how you would use this package from C#, Java/JSP, Swing, VB, Pro*C, Forms, Powerbuilder, a mobile phone, &lt;whatever the heck you want&gt;.&lt;br /&gt;&lt;br /&gt;–&lt;br /&gt;Storing application code in the database has had it's champions and detractors. &lt;br /&gt;&lt;br /&gt;When you start putting application code in the database, you are in the thoroughly non-portable arena. That code, were you to port your application to another database, would have to be rewritten. But think about your application mid-tier layer, will you port Java code to C#/.Net,-&gt; Pascal -&gt; C -&gt; VB, then to Python, Ruby on Rail ...etc., will you do that?&lt;br /&gt;&lt;br /&gt;Its very specificity to that database means it can also take advantage of, and wire close to that engine. There are situations where stored code in the database can be notably faster. Supposed you have to update some chunk of a million rows after doing some machinations on the data.&lt;br /&gt;&lt;br /&gt;In a stored procedure the data is read, manipulated, and updated in one step. Meanwhile if you did the same in your middle tier application code, you would have to send that data set over the network, do your manipulations, and send it back. Not only would it make this one task slower, but other transactions vying for that same data could potentially have to wait while that data is in transit, and being manipulated. Also, stored code can serve to encapsulate specific requests which can be invaluable at simplifying your overall application. All three databases support stored procedures and functions. Oracle also supports packages, or collections of stored procedures as well as various object oriented features, which almost no one ever uses. An additional note, a database engine actually context switches between stored code, and the SQL code embedded therein. As since of 9i, Oracle introduced bulk binding, so you can do work on large sets of rows, and update them all in one go, instead of each loop iteration. This feature can even further improve performance quite dramatically. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Document the SQL access database&lt;/strong&gt;&lt;br /&gt;We'll build a small application for this target, on Oracle APEX (HTML DB).&lt;br /&gt;then QA (and Developer) need to record all the SQL access db in the new developing applications.&lt;br /&gt;* SQL execution path&lt;br /&gt;* SQL performance statistics&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-4922547015258768075?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/4922547015258768075/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=4922547015258768075' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/4922547015258768075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/4922547015258768075'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2007/09/good-practice-middle-tier-dal-or_10.html' title='Good practice: Middle-tier DAL or Database API – Database access guideline'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-787452754917754272</id><published>2007-07-24T11:44:00.000-07:00</published><updated>2007-07-24T11:49:15.601-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='passion creative life'/><title type='text'>我年轻时所不了解的事情</title><content type='html'>-- 转贴子从 &lt;a href="http://www.lifebang.com/archives/411"&gt;生活帮-LifeBang&lt;/a&gt; &lt;br /&gt;-- 以供 自我勉励&lt;br /&gt;&lt;br /&gt;那些你曾经为之激动、兴奋，消耗了你无数时间和精力的事情，大多数是无足轻重的。 &lt;br /&gt;&lt;br /&gt;那些等着万事俱备才去做的事情往往永远也没机会做。 &lt;br /&gt;-- &lt;em&gt;&lt;strong&gt;立刻行动! 行动上热情!&lt;/strong&gt; &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;如果大家都抱怨你说你太特例独行与别人格格不入时，你一定在正确的轨道上。 &lt;br /&gt;如果工作是你全部的生活，你的生活就是一项艰苦的工作。 &lt;br /&gt;&lt;br /&gt;任何一个成功的人都有失败的时候。不要企图永远占据成功者的位置。 &lt;br /&gt;&lt;br /&gt;每件事都要花费计划中两倍的时间而只得到期望中一半的成果。没必要为此沮丧，认清现实，继续前进。 &lt;br /&gt;&lt;br /&gt;无论你怎么尝试改变，你总是你自己。 &lt;br /&gt;世界上最响的声音就是人们的抱怨声。别再让它更响了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-787452754917754272?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/787452754917754272/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=787452754917754272' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/787452754917754272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/787452754917754272'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2007/07/blog-post.html' title='我年轻时所不了解的事情'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-957657146045894871</id><published>2007-07-14T21:16:00.001-07:00</published><updated>2007-07-14T21:16:50.484-07:00</updated><title type='text'>PL/SQL 在 Oracle 11g 里面的功能完善: "continue"</title><content type='html'>Oracle 终于支持 CONTINUE 了, 像我一样 做 Development DBA 的人用得着了.&lt;br /&gt;原来老得翻翻文档, 找出 Label 和 GoTo的语法, 特别烦人.&lt;br /&gt;&lt;br /&gt;这个东西实在算不上一个新特性, 只能叫作功能完善而已.&lt;br /&gt;&lt;br /&gt;使用"CONTINUE" 的 PL/SQL程序样本, 请参考:&lt;br /&gt;&lt;a href="http://technology.amis.nl/blog/?p=2261"&gt;http://technology.amis.nl/blog/?p=2261&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-957657146045894871?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/957657146045894871/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=957657146045894871' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/957657146045894871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/957657146045894871'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2007/07/plsql-oracle-11g-continue.html' title='PL/SQL 在 Oracle 11g 里面的功能完善: &quot;continue&quot;'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-8505885207231908449</id><published>2006-12-08T17:51:00.001-08:00</published><updated>2006-12-08T17:51:56.456-08:00</updated><title type='text'>Database developers and Database API</title><content type='html'>I’ve come up with an idea while the new 6 months Oracle DBA contractor is being interviewed to back fill for Antoinette while she is on maternity leave. &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;The idea is we may take this Opportunity to introduce a new database developer join our team.&lt;br /&gt;&lt;br /&gt;We pay 6 months salary to the contractor and only get an actual 3 months of work since they need 3 months to get up to speed on our environment (together with the increased cost of hiring a contractor). &lt;br /&gt;&lt;br /&gt;It’s better to give this opportunity to the new employee as a database developer which can learn our business, and then contribute to our company in long term.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Why we need a Database Developer and Database API?&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Today some GUI logic is in the middle tier but most of the data logic is still in PL/SQL (let’s say eBay here).&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Performance&lt;br /&gt;Performance is directly connected to stability and functionality, when db node running to it’s knee and hangs, you can do nothing, and cause some potential locks and bugs.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Dodgy SQL examples.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;1) Filter data in java side, treat db as a black data store.&lt;br /&gt;We should always filter data from the database side, I knew it 10 years ago as a database developer.&lt;br /&gt;&lt;br /&gt;SELECT I.*&lt;br /&gt;&lt;br /&gt;FROM ABELISTING.XBNIDENTS I &lt;br /&gt;&lt;br /&gt;WHERE I.PROVIDER &lt;&gt; 44&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;What we did before:&lt;br /&gt;&lt;br /&gt;SELECT I.* FROM ABELISTING.XBNIDENTS I;&lt;br /&gt;&lt;br /&gt;Get all the data returned from database,&lt;br /&gt;&lt;br /&gt;And then filter the row &lt;&gt; 44 in Java side.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;2) Cursor fetches&lt;br /&gt;What we are doing:&lt;br /&gt;&lt;br /&gt;•          1. get Max and Min xbnidentsid&lt;br /&gt;&lt;br /&gt;SELECT MIN(XBNIDENTSID) AS MIN, MAX(XBNIDENTSID) AS MAX &lt;br /&gt;&lt;br /&gt;FROM ABELISTING.XBNIDENTS&lt;br /&gt;&lt;br /&gt;•          2. Split it into many 100 rows chunks by calculate each xbnidentsid range&lt;br /&gt;&lt;br /&gt;•          3. run below SELECT many times, each run get 100 rows&lt;br /&gt;&lt;br /&gt;SELECT I.*, R.RECOMMENDATIONSET&lt;br /&gt;&lt;br /&gt;FROM ABELISTING.XBNIDENTS I &lt;br /&gt;&lt;br /&gt;LEFT OUTER JOIN LIBRARYTHING.ISBNRECOMMENDATIONS R&lt;br /&gt;&lt;br /&gt;ON I.XBNIDENTIFIER = R.ISBN&lt;br /&gt;&lt;br /&gt;WHERE I.PROVIDER &lt;&gt; 44&lt;br /&gt;&lt;br /&gt;AND I.XBNIDENTTYPECODE = 1&lt;br /&gt;&lt;br /&gt;AND I.XBNIDENTSID &lt; #xbnidentsidMax#&lt;br /&gt;&lt;br /&gt;AND I.XBNIDENTSID &gt;= #xbnidentsidMin#&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;It’s a nest loop join, cost 5 times more resource and latches.&lt;br /&gt;&lt;br /&gt;Why not run a simple single SQL SELECT, hash join 2 tables, and use bulk cursor prefetch?&lt;br /&gt;&lt;br /&gt;It’s been implementing to X-Team, the rows Prefetching.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;2.1) change a simple UPDATE to 2 steps.&lt;br /&gt;1) select the PK_ID by some predicates, cached into Java server side, maybe run the SQL many times, return 100 rows each time.&lt;br /&gt;&lt;br /&gt;2) process row by row by PK_ID&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Why not run a single UPDATE SQL here?&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;3) Treat database as a black box or a human brain; actually, we control how database works, we need to have:&lt;br /&gt;•         knowledge of what the database is capable of doing&lt;br /&gt;&lt;br /&gt;•         knowledge of all of the intricacies of SQL&lt;br /&gt;&lt;br /&gt;•         knowledge a solid understanding of goal- what the question is&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Here is an example:&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;This SELECT takes 60 seconds.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;SELECT MIN(XBNIDENTSID) AS MIN, MAX(XBNIDENTSID) AS MAX &lt;br /&gt;&lt;br /&gt;FROM ABELISTING.XBNIDENTS;&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;| ID  | Operation             | NAME         | ROWS  | Bytes | COST (%CPU)| TIME     |&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;|   0 | SELECT STATEMENT      |              |     1 |     6 |  4564   (1)| 00:00:51 |&lt;br /&gt;&lt;br /&gt;|   1 |  SORT AGGREGATE       |              |     1 |     6 |            |          |&lt;br /&gt;&lt;br /&gt;|   2 |   INDEX FAST FULL SCAN| XBNIDENTS_PK |  6888K|    39M|  4564   (1)| 00:00:51 |&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;By simply break it down to 2 SELECT SQL, just 0.01 second&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;SELECT MIN(XBNIDENTSID) AS MIN&lt;br /&gt;&lt;br /&gt;FROM ABELISTING.XBNIDENTS&lt;br /&gt;&lt;br /&gt;UNION ALL&lt;br /&gt;&lt;br /&gt;SELECT MAX(XBNIDENTSID) AS MAX &lt;br /&gt;&lt;br /&gt;FROM ABELISTING.XBNIDENTS;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;| ID  | Operation                   | NAME         | ROWS  | Bytes | COST (%CPU)| TIME     |&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;|   0 | SELECT STATEMENT            |              |     2 |    12 |     6  (50)| 00:00:01 |&lt;br /&gt;&lt;br /&gt;|   1 |  UNION-ALL                  |              |       |       |            |          |&lt;br /&gt;&lt;br /&gt;|   2 |   SORT AGGREGATE            |              |     1 |     6 |            |          |&lt;br /&gt;&lt;br /&gt;|   3 |    INDEX FULL SCAN (MIN/MAX)| XBNIDENTS_PK |  6888K|    39M|     3   (0)| 00:00:01 |&lt;br /&gt;&lt;br /&gt;|   4 |   SORT AGGREGATE            |              |     1 |     6 |            |          |&lt;br /&gt;&lt;br /&gt;|   5 |    INDEX FULL SCAN (MIN/MAX)| XBNIDENTS_PK |  6888K|    39M|     3   (0)| 00:00:01 |&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Stability&lt;br /&gt;RDBMS database and store procedure have been around for more than 20 years, and is proven stable. Building our core data process logic inside the database will be stable.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;More components means more complexity, more coding and bugs, more maintenance job, and it’s not linear, it’s exponential.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;All about database API's. The applications don't do table level(select/insert/update/delete) stuff, the apps don't even really *know* about tables.&lt;br /&gt;&lt;br /&gt;On top of database schema we have an API that does the data stuff.&lt;br /&gt;In the application we call this API but have our own application logic as well&lt;br /&gt;(only application logic is in the application, data logic is -- well, right where it belongs -- next to the data, waiting for the 'next great programming paradigm to come along')&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;make software components modular &lt;br /&gt;software modules must carry out a very specific task&lt;br /&gt;(and be very efficient at carrying it out) &lt;br /&gt;each software module should be loosely coupled (to limit dependencies) &lt;br /&gt;It removes the need for triggers as all inserts, updates and deletes are wrapped in APIs. Instead of writing triggers you simply add the code into the API. I loath triggers. &lt;br /&gt;It prevents people who don't understand SQL writing stupid queries.&lt;br /&gt;All SQL would be written by PL/SQL developers or DBAs, reducing the likelyhood of dodgy queries. &lt;br /&gt;The underlying structure of the database is hidden from the users, so I can make structural changes without client applications being changed.The API implementation can be altered and tuned without affecting the client application. &lt;br /&gt;The same APIs are available to all applications that access the database. No duplication of effort. &lt;br /&gt;Flexibility and Elegant programming&lt;br /&gt;•         PL/SQL is the most efficient language for data manipulation&lt;br /&gt;&lt;br /&gt;–        PL/SQL datatypes are SQL datatypes collection/array, nest object table … – no conversions&lt;br /&gt;&lt;br /&gt;–        Tight coupling between the language and the database (cursor for loops for example)&lt;br /&gt;&lt;br /&gt;–        We don’t need to open/close queries – manage lots of stuff&lt;br /&gt;&lt;br /&gt;–        We are somewhat protected from changes in the database&lt;br /&gt;&lt;br /&gt;–        You have sub-optimizations like cursor caching done for you.&lt;br /&gt;(Native prefetch 100 rows, with FOR lc_cursor IN (select * from table_name) LOOP)&lt;br /&gt;&lt;br /&gt;–         &lt;br /&gt;&lt;br /&gt;•         Don’t forget the dependency mechanism you get!&lt;br /&gt;Drop/add columns and select * from table_name,&lt;br /&gt;Deploy at anytime after QA time, no build, no server restart, transparent when change table structure (physical database model)&lt;br /&gt;&lt;br /&gt;•         In PL/SQL it is very hard to not use bind variables correctly.&lt;br /&gt;&lt;br /&gt;•         In Java is it trivially easy to do it wrong – and it usually is.&lt;br /&gt;&lt;br /&gt;•         In PL/SQL – parse once, execute many is inherit in the environment.&lt;br /&gt;&lt;br /&gt;•         In Java, it must be coded – and it hardly ever is.&lt;br /&gt;&lt;br /&gt;•         In PL/SQL – “select *” can be safe (might not be the best approach, but is is “safe”)&lt;br /&gt;&lt;br /&gt;•         In Java – “select *” is deadly – but frequently used.&lt;br /&gt;&lt;br /&gt;•         PL/SQL can survive database schema changes such as a varchar2(80) -&gt; varchar2(255) change&lt;br /&gt;&lt;br /&gt;•         Java cannot, you will have to inspect all code and change variable sizes.&lt;br /&gt;&lt;br /&gt;•         PL/SQL has that nice builtin dependency mechanism to avoid the “I didn’t know you used that” syndrome&lt;br /&gt;&lt;br /&gt;•         Java does not.&lt;br /&gt;&lt;br /&gt;•         … a long list goes from her…&lt;br /&gt;&lt;br /&gt;•         Embed SQL complexity into store procedure, give a simple interface to Jave developer&lt;br /&gt;&lt;br /&gt;For example, book delete check:&lt;br /&gt;&lt;br /&gt;Packaged Store PROCEDURE list_df(p_cursor IN OUT listidcurtyp, p_string VARCHAR2)&lt;br /&gt;&lt;br /&gt; AS&lt;br /&gt;&lt;br /&gt;    i PLS_INTEGER;&lt;br /&gt;&lt;br /&gt; BEGIN&lt;br /&gt;&lt;br /&gt;      OPEN p_cursor FOR&lt;br /&gt;&lt;br /&gt;      WITH sq&lt;br /&gt;&lt;br /&gt;  AS&lt;br /&gt;&lt;br /&gt;   (&lt;br /&gt;&lt;br /&gt;     SELECT SUBSTR(x, INSTR(x,',',1,LEVEL)+1, INSTR(x,',',1,LEVEL+1) - INSTR(x,',',1,LEVEL) -1) token&lt;br /&gt;&lt;br /&gt;     FROM (SELECT ','||l_str||',' x,l_str FROM (SELECT p_string l_str FROM dual))&lt;br /&gt;&lt;br /&gt;     CONNECT BY LEVEL &lt;= LENGTH(l_str)-LENGTH(REPLACE(l_str,',',''))+1&lt;br /&gt;&lt;br /&gt;   )&lt;br /&gt;&lt;br /&gt;   SELECT A.listingsid listingsid&lt;br /&gt;&lt;br /&gt;   FROM abelisting.listings A, sq&lt;br /&gt;&lt;br /&gt;   WHERE A.listingsid = TO_NUMBER(sq.token)&lt;br /&gt;&lt;br /&gt;   AND A.rowdf = 'T';&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Java side: &lt;br /&gt;&lt;br /&gt;SELECT COLUMN_VALUE listingsid &lt;br /&gt;&lt;br /&gt;FROM TABLE(abelisting.Sp_Sql_Query.list_df_tabf(:l_string));&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Less code, simple is beautiful! &lt;br /&gt;Beat me if you can write less Java code for below PL/SQL store procedure to reach same goal, just to compare the simplicity, not mention the performance yet:&lt;br /&gt;&lt;br /&gt;1) For Loop&lt;br /&gt;CREATE OR REPLACE &lt;br /&gt;&lt;br /&gt;PROCEDURE process_data( p_inputs IN VARCHAR2 )&lt;br /&gt;&lt;br /&gt;AS &lt;br /&gt;&lt;br /&gt;BEGIN&lt;br /&gt;&lt;br /&gt;   FOR x IN ( SELECT * FROM EMP WHERE ename LIKE p_inputs )    &lt;br /&gt;&lt;br /&gt;   LOOP&lt;br /&gt;&lt;br /&gt;      Process( X );&lt;br /&gt;&lt;br /&gt;   END LOOP;&lt;br /&gt;&lt;br /&gt;END;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;2) Enforce read/write consistency, update and delete in one transaction&lt;br /&gt;PROCEDURE clear_pending_list_qty_forall&lt;br /&gt;&lt;br /&gt;  AS&lt;br /&gt;&lt;br /&gt;   TYPE listingsidList IS TABLE OF abelisting.list_qty_offset.listingsid%TYPE;&lt;br /&gt;&lt;br /&gt;   lt_listingsid listingsidList;&lt;br /&gt;&lt;br /&gt;   TYPE pendingList IS TABLE OF abelisting.list_qty_offset.pending%TYPE;&lt;br /&gt;&lt;br /&gt;   lt_pending pendingList;&lt;br /&gt;&lt;br /&gt;   l_cnt NUMBER;&lt;br /&gt;&lt;br /&gt;  BEGIN&lt;br /&gt;&lt;br /&gt;    DBMS_APPLICATION_INFO.SET_MODULE('ListLoad', 'Clear pending offset');&lt;br /&gt;&lt;br /&gt;      &lt;br /&gt;&lt;br /&gt;      --To clear all the pending ordered books qty, into listigns&lt;br /&gt;&lt;br /&gt;      --Using RETURNING collection to store processing data, make sure you can always get an consistent image of listings.qty&lt;br /&gt;&lt;br /&gt;      --that is, never delete the extra rows, between update and delete.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;   -- Options 2 is DELETE with RETURNING list, then bulk FORALL UPDATE, 2 times faster&lt;br /&gt;&lt;br /&gt;   DELETE FROM abelisting.list_qty_offset&lt;br /&gt;&lt;br /&gt;   RETURNING listingsid, pending BULK COLLECT INTO lt_listingsid, lt_pending;&lt;br /&gt;&lt;br /&gt;   &lt;br /&gt;&lt;br /&gt;   DEBUG.f('delete %s rows on abelisting.list_qty_offset', SQL%ROWCOUNT);&lt;br /&gt;&lt;br /&gt;   FORALL i IN lt_listingsid.FIRST .. lt_listingsid.LAST &lt;br /&gt;&lt;br /&gt;    UPDATE ABELISTING.listings SET quantity = quantity + lt_pending(i)&lt;br /&gt;&lt;br /&gt;        WHERE LISTINGSID = lt_listingsid(i);&lt;br /&gt;&lt;br /&gt;   l_cnt := SQL%ROWCOUNT;&lt;br /&gt;&lt;br /&gt;   DEBUG.f('updated qty on listing %s rows', l_cnt);&lt;br /&gt;&lt;br /&gt;   COMMIT;&lt;br /&gt;&lt;br /&gt;      /*&lt;br /&gt;&lt;br /&gt;      --Err logging&lt;br /&gt;&lt;br /&gt;      FOR i IN 1 .. lt_listingsid.COUNT&lt;br /&gt;&lt;br /&gt;      LOOP&lt;br /&gt;&lt;br /&gt;          DBMS_OUTPUT.PUT_LINE( 'updated listingsid = ' || lt_listingsid(i)||', qty = '||lt_pending(i) );&lt;br /&gt;&lt;br /&gt;              DEBUG.f( 'updated listingsid = ' || lt_listingsid(i)||', qty = '||lt_pending(i) );&lt;br /&gt;&lt;br /&gt;      END LOOP;&lt;br /&gt;&lt;br /&gt;    */&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;  EXCEPTION&lt;br /&gt;&lt;br /&gt;    WHEN OTHERS THEN&lt;br /&gt;&lt;br /&gt;        DEBUG.f( SUBSTR(TO_CHAR(SQLCODE)||': '||SQLERRM,1,100) );&lt;br /&gt;&lt;br /&gt;        RAISE;&lt;br /&gt;&lt;br /&gt;  END;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;3) INSERT … SELECT from external_table (flat file), data loading from flat file&lt;br /&gt;PROCEDURE isbn_recomd_full_load(p_add_rows IN OUT NUMBER)&lt;br /&gt;&lt;br /&gt; IS&lt;br /&gt;&lt;br /&gt;   l_cnt NUMBER;&lt;br /&gt;&lt;br /&gt; BEGIN&lt;br /&gt;&lt;br /&gt;   DBMS_APPLICATION_INFO.SET_MODULE('LB', 'isbn_recomd_full_load');&lt;br /&gt;&lt;br /&gt;   DEBUG.f('truncate table');&lt;br /&gt;&lt;br /&gt;   EXECUTE IMMEDIATE 'alter session set optimizer_mode=all_rows';&lt;br /&gt;&lt;br /&gt;   EXECUTE IMMEDIATE 'alter session set skip_unusable_indexes=true';&lt;br /&gt;&lt;br /&gt;   EXECUTE IMMEDIATE 'TRUNCATE TABLE librarything.isbnRecommendations';&lt;br /&gt;&lt;br /&gt;   DEBUG.f('unusable index');&lt;br /&gt;&lt;br /&gt;   --execute immediate 'alter index librarything.isbnRecommendations_isbn unusable';&lt;br /&gt;&lt;br /&gt;   DEBUG.f('INSERT +APPEND direct load');&lt;br /&gt;&lt;br /&gt;   INSERT /*+ APPEND */ INTO librarything.isbnRecommendations NOLOGGING&lt;br /&gt;&lt;br /&gt;   (isbn,recommendationSet)&lt;br /&gt;&lt;br /&gt;   SELECT isbn,recommendationSet&lt;br /&gt;&lt;br /&gt;   FROM librarything.isbnRecommendations_ext; -- the external table&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;   l_cnt := SQL%RowCount;&lt;br /&gt;&lt;br /&gt;   DEBUG.f('INSERTed %s rows', l_cnt);&lt;br /&gt;&lt;br /&gt;   COMMIT;&lt;br /&gt;&lt;br /&gt;   p_add_rows := l_cnt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;   DEBUG.f('rebuild index on isbn column');&lt;br /&gt;&lt;br /&gt;    ---execute immediate 'alter index librarything.isbnRecommendations_isbn rebuild online';&lt;br /&gt;&lt;br /&gt;   DEBUG.f('rebuild index done');&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;   DBMS_APPLICATION_INFO.SET_MODULE('LB', 'isbn_recomd_full_load done');&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;   EXCEPTION&lt;br /&gt;&lt;br /&gt;     WHEN OTHERS THEN&lt;br /&gt;&lt;br /&gt;      DEBUG.f( SUBSTR(TO_CHAR(SQLCODE)||': '||SQLERRM,1,100) );&lt;br /&gt;&lt;br /&gt;        RAISE;&lt;br /&gt;&lt;br /&gt; END;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;My Utopian Development Environment &lt;br /&gt;There is no SELECT/INSERT/UPDATE/DELETE/MERGE in Java code, the database access layer; only call a packaged database Store Procedure for a specific goal.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Communication&lt;br /&gt;Efficiency is achieved by specializing and profession, classify into Java developer, database developer and backend developer. JAVA handle file processing and UI logic, database process logic is just inside the database, wrapped into database store procedure.&lt;br /&gt;&lt;br /&gt;I know some backend developer can improve PL/SQL performance 8 times again by calling Pro*C or OCI*C code (Using SQL with array binds of 100 for Key Lookup and Insert), for the raw speed.&lt;br /&gt;&lt;br /&gt;A general knowledge to know all other party doing is also necessary and important.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Data modeling &lt;br /&gt;Design a sound data model is one of the most critical stages in the development of a computerized information system.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;We’re pursuing a Complete, no Redundancy, Enforce business rule, Data Reusable, flexible and stable, Elegant data model, also for Communication, Integration and &lt;br /&gt;&lt;br /&gt;Balance the Conflicting Objectives.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Please check attached email to see the problem could be easily solved by a fitted data model design; and how complex it is when you tackle this issue from Java world.&lt;br /&gt;&lt;br /&gt;For database developer, data model is part of their life.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-8505885207231908449?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/8505885207231908449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=8505885207231908449' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/8505885207231908449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/8505885207231908449'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2006/12/database-developers-and-database-api.html' title='Database developers and Database API'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-690099221740477729</id><published>2006-11-10T11:40:00.000-08:00</published><updated>2006-11-10T11:43:52.173-08:00</updated><title type='text'>Cascade DELETE</title><content type='html'># cascade delete -- that is a database feature. &lt;br /&gt;-- &lt;br /&gt;# validate foreign keys -- all should be (have to be) RI in the database as well. &lt;br /&gt;# cascade update -- well, won't even go there &lt;br /&gt;(which means you have an ill designed model in the first place as you &lt;br /&gt;are updating a primary key -- meaning it is not really a primary key at all). &lt;br /&gt;# for simple ins,upd,del,lck -- it is just as easy to code....., into Data API. &lt;br /&gt;&lt;br /&gt;I don't like it(cascade delete) personally -- I'd rather have an error when I delete a parent &lt;br /&gt;that has child records. Doesn't "seem" right to have that stuff just disappear. &lt;br /&gt;&lt;br /&gt;It is useful in limited cases. &lt;br /&gt;if and only if EVERY time you delete from parent you want to delete from child, &lt;br /&gt;on delete cascade is OK. &lt;br /&gt;but, if there are sometimes that is not the expected behavior -- don't do that, --such as customer and orders. &lt;br /&gt;use a stored procedure/(Database API). &lt;br /&gt;&lt;br /&gt;All access would be provided by PL/SQL APIs. I like this because: &lt;br /&gt;It removes the need for triggers as all inserts, updates and deletes are wrapped in APIs. Instead of writing triggers you simply add the code into the API. I loath triggers.&lt;br /&gt;&lt;br /&gt;And, at last, make sure to index those foreign keys, else either approach would be slow slow slow. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You can only have on delete cascade when creating the constraint &lt;br /&gt;(so you drop and recreate the constraint) &lt;br /&gt;&lt;br /&gt;Cascade DELETE example: &lt;br /&gt;&lt;br /&gt;drop table t1; &lt;br /&gt;create table t1 ( x int primary key ); &lt;br /&gt;create table t2 ( y int primary key, x &lt;br /&gt;references t1 on delete cascade ); &lt;br /&gt;create table t3 ( y references t2 on delete &lt;br /&gt;cascade, x references t1 ); &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;insert into t1 values ( 1 ); &lt;br /&gt;insert into t2 values ( 1 , 1 ); &lt;br /&gt;insert into t3 values ( 1 , 1 ); &lt;br /&gt;&lt;br /&gt;delete from t1; &lt;br /&gt;&lt;br /&gt;select * from t1; &lt;br /&gt;select * from t2; &lt;br /&gt;select * from t3; &lt;br /&gt;&lt;br /&gt;Formal way to add cascade delete constraint: &lt;br /&gt;&lt;br /&gt;ALTER table c &lt;br /&gt; add constraint c_fk_parent_table &lt;br /&gt; foreign key(x) references p(x) &lt;br /&gt;on delete cascade;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-690099221740477729?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/690099221740477729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=690099221740477729' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/690099221740477729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/690099221740477729'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2006/11/cascade-delete-that-is-database-feature.html' title='Cascade DELETE'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-5182629919128962077</id><published>2006-11-01T22:04:00.000-08:00</published><updated>2006-11-01T22:06:08.686-08:00</updated><title type='text'>General Knowledge</title><content type='html'>唉, 我就爱尝鲜, 对每个新特性如获至宝, 记得2001年秋天, 就给世界第二大长话公司上了Oracle 9i on HP-UX.&lt;br /&gt;我的老板(Borland J Builder 的首席构架师)总喜欢问: 啥时候换MySQL呀,要不MS-SQL 2005 也行 (整天宣传SQL-Server2005的优越性), 前两天又来了个 Enterprise DB (基于Postgres)&lt;br /&gt;像我这样只懂Oracle的 咋办呀?!!(我就建议老板 试试DB2还行 我有认证)&lt;br /&gt;还好-最近的统计显示Oracle市场占有率超过50%.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-5182629919128962077?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/5182629919128962077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=5182629919128962077' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/5182629919128962077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/5182629919128962077'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2006/11/general-knowledge.html' title='General Knowledge'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-7309820235895938072</id><published>2006-11-01T10:00:00.000-08:00</published><updated>2009-01-13T14:40:55.208-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='partition'/><category scheme='http://www.blogger.com/atom/ns#' term='data guard'/><category scheme='http://www.blogger.com/atom/ns#' term='11g'/><category scheme='http://www.blogger.com/atom/ns#' term='compress'/><category scheme='http://www.blogger.com/atom/ns#' term='standby'/><title type='text'>Oracle  Data Guard and 11g database</title><content type='html'>浏览了Fenng的 一篇 Oracle Data Guard practice, 被 control file 搞懵了.&lt;br /&gt;看来我比你幸运,从来没有考虑过copy standby db control file.&lt;br /&gt;我们的配置是, 4 nodes RAC 10.1.0.4, 1 real time standby, 1 read-only standby, for reporting, refresh every night.跑了一年多了 啥问题也没有 可惜Logcial stdby 不支持宽表(100+ columns)等升级到10.2.0.3,会加一个Logical Standby.&lt;br /&gt;&lt;br /&gt;根据我的经验,Oracle 整体稳定,但总有一些莫名其妙的Bug,我们的宗旨是: "绕过去, 别较劲"&lt;br /&gt;&lt;br /&gt;读了一些Blog, 谈论Oracle database的下一个版本.&lt;br /&gt;Oracle db 11g&lt;br /&gt;Partition&lt;br /&gt;(a. Time dimension and&lt;br /&gt; b. Child table partition based on master tables partition columns&lt;br /&gt;)&lt;br /&gt;和数据压缩, 令人神往. 嘻嘻.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-7309820235895938072?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/7309820235895938072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=7309820235895938072' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/7309820235895938072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/7309820235895938072'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2006/11/oracle-data-guard-and-10g-database.html' title='Oracle  Data Guard and 11g database'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-7566021816475388829</id><published>2006-10-27T14:50:00.000-07:00</published><updated>2010-10-12T14:54:13.222-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Database API'/><title type='text'>Data API -- Data access and process interface</title><content type='html'>Some other2 reasons to implement Data&lt;span style="color: #009900;"&gt;base&lt;/span&gt; API&lt;br /&gt;I) Binding Variable, naturally, implicitly.&lt;br /&gt;II) do set based process (100 rows array prefetch by default) to FOR LOOP.&lt;br /&gt;III) debug.f : to Instrument the code&lt;br /&gt;&lt;br /&gt;&lt;a href="http://oracle-base.blogspot.com/2005/06/my-utopian-development-environment.html"&gt;Compulsory PL/SQL APIs&lt;/a&gt;&lt;br /&gt;Client application developers would have no direct access to tables. Not even for queries. All access would be provided by PL/SQL APIs (Include database Views).&lt;br /&gt;&lt;br /&gt;I like this because:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It removes the need for triggers as all inserts, updates and deletes are wrapped in APIs. Instead of writing triggers you simply add the code into the API. I loath triggers. &lt;/li&gt;&lt;li&gt;It prevents people who don't understand SQL writing stupid queries.&lt;br /&gt;All SQL would be written by PL/SQL developers or DBAs, reducing the likelyhood of dodgy queries. &lt;/li&gt;&lt;li&gt;The underlying structure of the database is hidden from the users, so I can make structural changes without client applications being changed.The API implementation can be altered and tuned without affecting the client application. &lt;/li&gt;&lt;li&gt;The same APIs are available to all applications that access the database. No duplication of effort.&lt;/li&gt;&lt;/ul&gt;Anything that generates SQL on-the-fly worries me, not just Java. I want to be able to cut and paste the SQL, not try and capture or trace it during a run.&lt;br /&gt;&lt;br /&gt;Our concept is "&lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:25405782527721"&gt;build the data API in the database, you call the data API&lt;/a&gt;".&lt;br /&gt;Database API has been layered by different UI technologies over time.&lt;br /&gt;&lt;br /&gt;All about API's. The applications don't do &lt;strong&gt;table level&lt;/strong&gt;&lt;span style="color: #3366ff;"&gt;(&lt;span style="color: #ff6600;"&gt;select/insert/update/delete&lt;/span&gt;)&lt;/span&gt; stuff, the apps don't even really *know* about tables.&lt;br /&gt;&lt;br /&gt;On top of database schema we have an API that does the data stuff.&lt;br /&gt;In the application we call this API but have our own application logic as well&lt;br /&gt;(only application logic is in the application, data logic is -- well, right where it belongs -- next to the data, waiting for the 'next great programming paradigm to come along')&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;make software components modular&lt;/li&gt;&lt;li&gt;software modules must carry out a very specific task&lt;br /&gt;(and be very efficient at carrying it out) &lt;/li&gt;&lt;li&gt;each software module should be loosly coupled (to limit dependencies)&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-7566021816475388829?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/7566021816475388829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=7566021816475388829' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/7566021816475388829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/7566021816475388829'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2006/10/data-api.html' title='Data API -- Data access and process interface'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8612611874818330035.post-2406952661318468405</id><published>2006-10-27T14:22:00.000-07:00</published><updated>2006-10-27T14:23:14.951-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle DBA'/><title type='text'>木匠铺子开张啦</title><content type='html'>Oracle 技术版&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8612611874818330035-2406952661318468405?l=mujiang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mujiang.blogspot.com/feeds/2406952661318468405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8612611874818330035&amp;postID=2406952661318468405' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/2406952661318468405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8612611874818330035/posts/default/2406952661318468405'/><link rel='alternate' type='text/html' href='http://mujiang.blogspot.com/2006/10/blog-post.html' title='木匠铺子开张啦'/><author><name>Charlie 1 木匠</name><uri>http://www.blogger.com/profile/14655756353501513388</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_Wv9Lui_cURQ/R3H4MY2XtnI/AAAAAAAAACM/3ZJtUFfVnG8/S220/SunLiRen.jpg'/></author><thr:total>0</thr:total></entry></feed>
