We are really looking forward your next book
Lakshmi narasimhan R, January   06, 2003 - 2:14 am UTC
 
 
Hi tom
We will be Glad if we get your book.  We will be really happy if you can include how to read Explain Plan and its different meanings and interpretations. Even though its been with lot of books including Oracle Documentation, i am of the opinion that it is not in easy word.  Bit hard and confusing way.  We hope you can give it in straight forward simple way.
thanks in advance. 
 
January   06, 2003 - 7:45 am UTC 
 
 
I'm not doing that -- I find the performance guide does it well?   do you have a specific question.  it is just a tree???  it is pretty straight forward to read.
Give me a question and I'll answer it -- but I'm not going to write how to read it as that is well documented. 
 
 
 
Oracle SQL Tuning Book
Moorthy Rekapalli, January   06, 2003 - 10:48 am UTC
 
 
Hi,
First of all, let me thank Tom and his team for their contributions to the Oracle community.  I learned a lot from Tom's book.
Oracle SQL High-Performance Tuning by Guy Harrison is a very good book that is dedicated to different access paths, how to interpret explain plan, tkprof etc...
This book will be a very good companion to Tom's Oracle expert one-on-one book.
Just thought of sharing my 2 cents with the Oracle community.
Hope this helps,
Moorthy Rekapalli.
 
 
 
an idea for the next book :)
John, January   06, 2003 - 12:12 pm UTC
 
 
when you are all done, break it into 3 volumns and INCREASE THE POINT SIZE!!!! :)
You'll be able to sell 3 books, and each will have more info than most, and I'll be able to read 2 chapters without getting a headache!
(what where you using on Expert? 2-point, 3-point?)
(maybe I'm just getting old)
Thanks for the knowledge
 
 
January   06, 2003 - 12:26 pm UTC 
 
 
Hey -- I write it on 21" crt's or 20" lcds (bought myself a christmas present for at home -- a pair of 20" lcd monitors -- man does that jam!).
The fonts are big to me when I look at them ;)
Seriously -- I'll send this along to WROX -- they do that stuff, I have no control over it really. 
 
 
 
I'm glad I had a part in that!
John, January   06, 2003 - 1:07 pm UTC
 
 
(financing you Christmas present):)
I've been through the appendixes and just started the
first few chapters. Very well written and informative.
Your Joe User style makes it an easy read (once I put the bottlenecks on, \OO/ heh, heh)
I can't express enough how useful this sight has been for me.
(btw I also have an LCD 17" and find it too "crisp")
If "Knowledge is Power" you are one with much power.
Looking forward to the next book (or 3)
Thanks again 
 
 
Your next book
A reader, January   06, 2003 - 2:30 pm UTC
 
 
Hi Tom,
When is your 3rd book out? May I peek the table of contents? Is there any draft on the web site?
I just can't wait to get your new book. Thanks! 
Steve
    
 
January   06, 2003 - 3:26 pm UTC 
 
 
 
 
Print of Expert one on one
A reader, January   06, 2003 - 4:43 pm UTC
 
 
Tom,
Just to let you know that I buy books and try to read books as soon as possible (before new version of book or software version is available, and I loose interest), and I did the same with your book. But I also found the print hard to read (I am talking of printing from WROX here). In fact, when I first bought and tried to read, I just stopped because of print. But more I visited your site, more I came to know about your authority on the subject, and I have started reading again, but print wise it is really hard to read. I know print of O'Reilly books <> print of WROX books but I found print of O'Reilly is really comfortable for which I have already written to wrox.
Regards,
 
 
 
fast query
ASHRAF, January   07, 2003 - 6:43 am UTC
 
 
in data warehouse database i need to run the query fast and i care about only how can i get output fast so i wonder about  CBO IT IS MAY BE not the fast 
 
January   08, 2003 - 2:04 pm UTC 
 
 
In a datawarehouse -- CBO is the only way to go....
bitmap indexes = CBO
partitioning = CBO
parallel = CBO
function based indexes = CBO
star transformations = CBO
materialized views = CBO
my point would be, if you stand up a data warehouse and DON'T use the CBO, you got it sdrawkcab  -- thats backwards ;) 
 
 
 
A reader, January   07, 2003 - 1:48 pm UTC
 
 
Tom,
Just a suggestion, is it possible to get the archives of Q & A from this site on cdrom based on dates.It will be a cool thing to have.I am pretty much sure viewers of this site don't mind to spend some amount if need be.
Thanks.
 
 
January   08, 2003 - 2:39 pm UTC 
 
 
nope, all online, all of the time.
feel free to download -- i try to make that really easy.  A simple "save link to disk" and that week it done. 
 
 
 
archiving asktom
hrishy, January   22, 2003 - 3:37 am UTC
 
 
Hi Tom
certainly this is a great place to be for any kinda of technology releated question..wheather your a DBA/developer or you have anythin remotely to do with oracle :-D..so  many times i find myself archiving the threads some of them for the way the query was written..some for innovative way of explaning things (my favourite one being consistent gets ;-D)..but when i try to save it this web page it has  some funny name which i later change to the topic of the thread.
1)Can we have an option of saving it by thread name when i save it to the disk (i am just being lazy of renaming )
2)what is the problem with oracle folks burning this forum on a CD and selling it or bundling it along with your books..as i find it handy when i visit client places ..just the way i carry oracle manuals ..as we dont have internet acesses at many client places..as increasingly find myself slightly modify your query to come out with innovative solutions to problems 
 
January   22, 2003 - 8:16 am UTC 
 
 
1) at the bottom of every article is a:
Bookmark this page with the link HERE
link -- that gives you a clean URL that won't change over time.
2) I don't get it -- just goto the archive by week and "save link to disk".  there you go.  
the second I put it onto CD, it's out of date.  It takes seconds to download a weeks worth of stuff -- you can put it on a floppy or burn a CD from it or just put it on your laptop....
It is a matter of distribution, time, etc.... 
 
 
 
With regards to...
Kashif, January   22, 2003 - 2:12 pm UTC
 
 
"Mastering all aspects of the SQL language.  Tell me -- can you in a single query 
tell me what the most frequently occuring object_type in your database is?  That 
is -- just write a query that returns the name(s) of the object_type that has 
the highest count(*).  I can do it in so many different ways -- many people 
cannot do it without writing code."
I've come up with two, using techniques I learned from this site:
select object_type 
  from all_objects
 group by object_type
having count (object_type) >= ALL (select count (object_type)
from all_objects
group by object_type)
AND
select object_type from
(
select object_type, count (object_type) cnt
from all_objects
group by object_type
order by cnt desc
)
where rownum = 1
Can you show us some other queries to solve the same problem? The first of my queries runs for quite a bit, which makes sense since there's so much sorting going on. Thanks.
Kashif 
 
January   22, 2003 - 2:34 pm UTC 
 
 
well -- your queries point out an interesting issue with this question.  
ops$tkyte@ORA920> create table t
  2  as
  3  select * from all_objects
  4   where object_type not in ( 'JAVA CLASS', 'SYNONYM' );
Table created.
ops$tkyte@ORA920>
ops$tkyte@ORA920> create trigger t_trigger before insert on t for each row
  2  begin
  3          select decode(:new.object_type,'TABLE','VIEW','TABLE')
  4            into :new.object_type
  5            from dual;
  6  end;
  7  /
Trigger created.
ops$tkyte@ORA920> insert into t select * from t where object_type in ( 'TABLE', 'VIEW' );
3566 rows created.
ops$tkyte@ORA920>
ops$tkyte@ORA920> select object_type, count(*)
  2    from t
  3   group by object_type
  4   order by 2
  5  /
OBJECT_TYPE          COUNT(*)
------------------ ----------
CONSUMER GROUP              2
MATERIALIZED VIEW           4
CONTEXT                     6
LOB                         6
DIRECTORY                   9
INDEXTYPE                   9
EVALUATION CONTEXT         11
RULE SET                   15
JAVA SOURCE                18
OPERATOR                   28
PROCEDURE                  50
TABLE PARTITION            61
TYPE BODY                  61
TRIGGER                    95
LIBRARY                   104
SEQUENCE                  127
INDEX PARTITION           134
FUNCTION                  147
JAVA RESOURCE             190
JAVA DATA                 291
PACKAGE BODY              533
PACKAGE                   590
TYPE                      862
INDEX                    1043
TABLE                    3566
VIEW                     3566
26 rows selected.
ops$tkyte@ORA920>
ops$tkyte@ORA920> select object_type
  2    from t
  3   group by object_type
  4  having count (object_type) >= ALL (select count (object_type)
  5                                       from t
  6                                      group by object_type)
  7  /
OBJECT_TYPE
------------------
TABLE
VIEW
ops$tkyte@ORA920>
ops$tkyte@ORA920> select object_type
  2    from ( select object_type, count (object_type) cnt
  3             from t
  4            group by object_type
  5            order by cnt desc
  6     )
  7   where rownum = 1
  8  /
OBJECT_TYPE
------------------
TABLE
ops$tkyte@ORA920>
So, which one is right?  both are, neither is, the first one is, the second one is.  Depends on your perspective..... (eg: the question is ambigous ;)
Anyway -- here are some others:
ops$tkyte@ORA920> select *
  2    from (
  3  select object_type, row_number() over ( order by cnt desc nulls last ) rn
  4    from ( select object_type, count(*) cnt
  5             from t
  6            group by object_type )
  7         )
  8   where rn = 1
  9  /
OBJECT_TYPE                RN
------------------ ----------
TABLE                       1
ops$tkyte@ORA920>
ops$tkyte@ORA920> select * from (
  2  select object_type, cnt, max(cnt) over () max_cnt
  3    from ( select distinct object_type,
  4                  count(*) over (partition by object_type) cnt
  5             from t )
  6  ) where cnt = max_cnt
  7  /
OBJECT_TYPE               CNT    MAX_CNT
------------------ ---------- ----------
TABLE                    3566       3566
VIEW                     3566       3566
ops$tkyte@ORA920>
ops$tkyte@ORA920> select object_type
  2    from t
  3   group by object_type
  4  having count(*) = ( select max(count(*))
  5                        from t
  6                       group by object_type )
  7  /
OBJECT_TYPE
------------------
TABLE
VIEW
ops$tkyte@ORA920>
ops$tkyte@ORA920> select substr( max( to_char(count(*),'fm0000000000009')||object_type ), 14 )
  2    from t
  3   group by object_type
  4  /
SUBSTR(MAX(TO_CHAR(
-------------------
VIEW
 
 
 
 
 
A reader, January   22, 2003 - 3:05 pm UTC
 
 
Hi Tom,
 You are using ALL operator in sql query.
 What is that ?
ops$tkyte@ORA920>
ops$tkyte@ORA920> select object_type
  2    from t
  3   group by object_type
  4  having count (object_type) >= ALL (select count  (object_type) <------
  5                                       from t
  6                                      group by object_type) 
  7  /
 
 
January   22, 2003 - 3:13 pm UTC 
 
 
just read it.
lines 4-6 in english are:
keep the rows having the count that is greater than or equal to ALL of the counts by object type....
There is an ANY modifier as well --   expression <operator> ANY ( set )  just like
                                      expression <operator> ALL ( set )
 
 
 
 
again, a definition might be of help here...
A reader, January   22, 2003 - 3:28 pm UTC
 
 
At the Mirriam-Webster webiste,
</code>  
http://www.m-w.com/  <code>
the following definition for the word 'ALL' was found:
1 a : the whole amount or quantity of <needed all the courage they had> <sat up all night> b : as much as possible <spoke in all seriousness>
2 : every member or individual component of <all men will go> <all five children were present>
3 : the whole number or sum of <all the angles of a triangle are equal to two right angles>
4 : EVERY <all manner of hardship>
5 : any whatever <beyond all doubt>
6 : nothing but : ONLY: a : completely taken up with, given to, or absorbed by <became all attention> b : having or seeming to have (some physical feature) in conspicuous excess or prominence <all legs> c : paying full attention with <all ears>
7 dialect : used up : entirely consumed -- used especially of food and drink
8 : being more than one person or thing <who all is coming>
synonym see WHOLE
- all the : as much of... as : as much of a... as <all the home I ever had>   
 
 
compare the two queries
Winston, January   22, 2003 - 6:44 pm UTC
 
 
I compared the last two ways using runSTAT, one approach is running faster then another, but occupying more cache buffer chain latch, shared pool latch  but with less library cache latch.
Which approach would you choose to use and why? How do you compare the cost of different latches?
Thanks
declare
  2      l_start number;
  3      l_run1  number;
  4      l_run2  number;
  5  
  6      type rc is ref cursor;
  7      l_rc    rc;
  8  begin
  9      insert into run_stats select 'before', stats.* from stats;
 10  
 11      l_start := dbms_utility.get_time;
 12      for i in 1 .. 1000
 13      loop
 14          open l_rc for 'select object_type
 15                        from t
 16                       group by object_type
 17                      having count(*) = ( select max(count(*))
 18                                            from t
 19                                           group by object_type )';
 20          close l_rc;
 21      end loop;
 22      l_run1 := (dbms_utility.get_time-l_start);
 23      dbms_output.put_line( l_run1 || ' hsecs' );
 24  
 25      insert into run_stats select 'after 1', stats.* from stats;
 26      l_start := dbms_utility.get_time;
 27      for i in 1 .. 1000
 28      loop
 29          open l_rc for 'select substr( max(
 30                      to_char(count(*),''fm0000000000009'')||object_type ), 14 )
 31                            from t
 32                           group by object_type' ;
 33          close l_rc;
 34      end loop;
 35      l_run2 := (dbms_utility.get_time-l_start);
 36      dbms_output.put_line( l_run2 || ' hsecs' );
 37      dbms_output.put_line
 38      ( 'run 1 ran in ' || round(l_run1/l_run2*100,2) || '% of the time' );
 39  
 40      insert into run_stats select 'after 2', stats.* from stats;
 41  end;
 42  /
27 hsecs
36 hsecs
run 1 ran in 75% of the time
PL/SQL procedure successfully completed.
select a.name, b.value-a.value run1, c.value-b.value run2,
  2         ( (c.value-b.value)-(b.value-a.value)) diff
  3    from run_stats a, run_stats b, run_stats c
  4   where a.name = b.name
  5     and b.name = c.name
  6     and a.runid = 'before'
  7     and b.runid = 'after 1'
  8     and c.runid = 'after 2'
  9     and (c.value-a.value) > 0
 10     and (c.value-b.value) <> (b.value-a.value)
 11   order by abs( (c.value-b.value)-(b.value-a.value))
 12  /
NAME                                                                                   RUN1
-------------------------------------------------------------------------------- ----------
      RUN2       DIFF
---------- ----------
LATCH.cache buffers lru chain                                                             1
         0         -1
LATCH.checkpoint queue latch                                                              2
         3          1
LATCH.undo global data                                                                    0
         1          1
LATCH.session allocation                                                                  1
         0         -1
STAT...messages sent                                                                      0
         1          1
STAT...session cursor cache hits                                                       1000
      1001          1
STAT...free buffer requested                                                              3
         2         -1
STAT...table fetch continued row                                                          2
         0         -2
STAT...redo entries                                                                      16
        13         -3
LATCH.redo allocation                                                                    15
        19          4
STAT...sorts (memory)                                                                     8
         4         -4
STAT...enqueue releases                                                                   7
         3         -4
STAT...cluster key scans                                                                  5
         0         -5
STAT...session cursor cache count                                                         5
         0         -5
STAT...recursive cpu usage                                                               31
        36          5
STAT...enqueue requests                                                                   8
         3         -5
STAT...db block changes                                                                  27
        22         -5
LATCH.enqueue hash chains                                                                12
         6         -6
STAT...opened cursors current                                                             7
         1         -6
STAT...parse time cpu                                                                     5
        12          7
STAT...parse time elapsed                                                                 5
        12          7
STAT...db block gets                                                                     25
        17         -8
LATCH.messages                                                                            3
        13         10
STAT...cluster key scan block gets                                                       10
         0        -10
LATCH.enqueues                                                                           24
        12        -12
LATCH.library cache load lock                                                            14
         0        -14
STAT...rows fetched via callback                                                         18
         0        -18
STAT...opened cursors cumulative                                                       1024
      1005        -19
STAT...sorts (rows)                                                                    2117
      2085        -32
STAT...parse count (total)                                                             1038
      1005        -33
STAT...execute count                                                                   1042
      1005        -37
STAT...calls to get snapshot scn: kcmgss                                               1043
      1005        -38
STAT...redo size                                                                      21552
     21512        -40
STAT...buffer is pinned count                                                            49
         0        -49
LATCH.row cache objects                                                                 142
        72        -70
STAT...table fetch by rowid                                                              85
         8        -77
STAT...no work - consistent read gets                                                    93
         8        -85
STAT...buffer is not pinned count                                                       179
        16       -163
STAT...consistent gets                                                                  209
        12       -197
STAT...session logical reads                                                            234
        29       -205
LATCH.cache buffers chains                                                              412
       115       -297
STAT...recursive calls                                                                 3506
      3030       -476
LATCH.shared pool                                                                      1322
       146      -1176
LATCH.library cache                                                                    2714
      5256       2542
STAT...session uga memory                                                             -4264
     27464      31728
45 rows selected. 
 
January   23, 2003 - 7:39 am UTC 
 
 
well, i would not run it using NDS, and when I run it statically:
ops$tkyte@ORA920> declare
  2      l_start number;
  3      l_run1  number;
  4      l_run2  number;
  5
  6      l_seq   number;
  7  begin
  8      insert into run_stats select 'before', stats.* from stats;
  9
 10      l_start := dbms_utility.get_time;
 11      for i in 1 .. 100
 12      loop
 13          for x in ( select object_type
 14                       from t
 15                      group by object_type
 16                     having count(*) = (select max(count(*))
 17                                          from t
 18                                         group by object_type ) )
 19          loop
 20              null;
 21          end loop;
 22      end loop;
 23      l_run1 := (dbms_utility.get_time-l_start);
 24      dbms_output.put_line( l_run1 || ' hsecs' );
 25
 26      insert into run_stats select 'after 1', stats.* from stats;
 27      l_start := dbms_utility.get_time;
 28      for i in 1 .. 100
 29      loop
 30          for x in ( select substr( max(to_char(count(*),'fm0000000000009')||object_type ), 14 )
 31                       from t
 32                      group by object_type )
 33          loop
 34              null;
 35          end loop;
 36      end loop;
 37      l_run2 := (dbms_utility.get_time-l_start);
 38      dbms_output.put_line( l_run2 || ' hsecs' );
 39      dbms_output.put_line
 40      ( 'run 1 ran in ' || round(l_run1/l_run2*100,2) || '% of the time' );
 41
 42      insert into run_stats select 'after 2', stats.* from stats;
 43  end;
 44  /
230 hsecs
120 hsecs
run 1 ran in 191.67% of the time
PL/SQL procedure successfully completed.
I get totally the opposite of your results -- 0.27 seconds for 1,000 executions is a pretty fast number to say the least -- these stats:
STAT...consistent gets                                                           
       209
        12       -197
STAT...session logical reads                                                     
       234
        29       -205
show that your table was pretty much "empty"??
 
 
 
 
 
I missed the fetch of ref cursor...table contains 4123 records
Winston, January   24, 2003 - 5:49 pm UTC
 
 
HOw do you interprete the following benchmark difference?
run 1 ran in 183.91% of the time but took less consistent gets and session logic reads. Details as below
declare
    l_start number;
    l_run1  number;
    l_run2  number;
    l_object_type t.object_type%type;
    
    type rc is ref cursor;
    l_rc    rc;
begin
    insert into run_stats select 'before', stats.* from stats;
    l_start := dbms_utility.get_time;
    for i in 1 .. 100
    loop
        open l_rc for 'select object_type from (
                                select object_type, cnt, max(cnt) over () max_cnt
                                  from ( select distinct object_type,
                                                count(*) over (partition by object_type) cnt
                                           from t )
                                ) where cnt = max_cnt';
          loop
                   fetch l_rc into l_object_type;
                   exit when l_rc%notfound;           
           end loop;
           close l_rc;     
    end loop;
    l_run1 := (dbms_utility.get_time-l_start);
    dbms_output.put_line( l_run1 || ' hsecs' );
 
    insert into run_stats select 'after 1', stats.* from stats;
    l_start := dbms_utility.get_time;
    for i in 1 .. 100
    loop
        open l_rc for 'select object_type
                      from t
                     group by object_type
                    having count(*) = ( select max(count(*))
                                          from t
                                         group by object_type )';
          loop
                   fetch l_rc into l_object_type;
                   exit when l_rc%notfound;           
          end loop;
          close l_rc;
        
    end loop;
    l_run2 := (dbms_utility.get_time-l_start);
    dbms_output.put_line( l_run2 || ' hsecs' );
    dbms_output.put_line
    ( 'run 1 ran in ' || round(l_run1/l_run2*100,2) || '% of the time' );
    insert into run_stats select 'after 2', stats.* from stats;
end;
/
pause
select a.name, b.value-a.value run1, c.value-b.value run2,
       ( (c.value-b.value)-(b.value-a.value)) diff
  from run_stats a, run_stats b, run_stats c
 where a.name = b.name
   and b.name = c.name
   and a.runid = 'before'
   and b.runid = 'after 1'
   and c.runid = 'after 2'
   and (c.value-a.value) > 0
   and (c.value-b.value) <> (b.value-a.value)
 order by abs( (c.value-b.value)-(b.value-a.value))
/
      RUN2       DIFF
---------- ----------
LATCH.active checkpoint queue latch                                                       2
         1         -1
LATCH.session allocation                                                                  1
         0         -1
LATCH.undo global data                                                                    0
         1          1
STAT...cursor authentications                                                             0
         1          1
STAT...messages sent                                                                      0
         1          1
STAT...opened cursors current                                                             3
         4          1
STAT...session cursor cache hits                                                        100
       101          1
STAT...free buffer requested                                                              3
         2         -1
STAT...cluster key scans                                                                  2
         1         -1
LATCH.cache buffers lru chain                                                             2
         0         -2
STAT...parse time elapsed                                                                 4
         2         -2
STAT...table fetch continued row                                                          2
         0         -2
LATCH.redo writing                                                                        8
         5         -3
STAT...redo entries                                                                      16
        13         -3
LATCH.redo allocation                                                                    15
        19          4
STAT...cluster key scan block gets                                                        2
         6          4
STAT...db block changes                                                                  27
        22         -5
STAT...enqueue releases                                                                   7
         2         -5
STAT...session cursor cache count                                                         5
         0         -5
STAT...enqueue requests                                                                   8
         2         -6
LATCH.enqueue hash chains                                                                12
         4         -8
LATCH.library cache load lock                                                            10
         2         -8
STAT...opened cursors cumulative                                                        119
       108        -11
LATCH.enqueues                                                                           24
         8        -16
STAT...rows fetched via callback                                                         18
         0        -18
STAT...execute count                                                                    133
       112        -21
STAT...calls to get snapshot scn: kcmgss                                                134
       112        -22
STAT...parse count (total)                                                              133
       108        -25
STAT...redo size                                                                      21508
     21468        -40
LATCH.checkpoint queue latch                                                             98
        51        -47
LATCH.row cache objects                                                                 126
        78        -48
STAT...buffer is pinned count                                                            49
         0        -49
STAT...table fetch by rowid                                                              80
        13        -67
STAT...table scans (short tables)                                                       100
       200        100
STAT...sorts (memory)                                                                   308
       204       -104
LATCH.shared pool                                                                       412
       246       -166
STAT...recursive cpu usage                                                              431
       237       -194
STAT...recursive calls                                                                  974
       701       -273
LATCH.library cache                                                                     855
       497       -358
STAT...db block gets                                                                    424
       817        393
STAT...sorts (rows)                                                                  827917
    826685      -1232
STAT...consistent gets                                                                 5376
     10439       5063
STAT...buffer is not pinned count                                                      5357
     10436       5079
STAT...no work - consistent read gets                                                  5276
     10423       5147
STAT...table scan blocks gotten                                                        5200
     10400       5200
STAT...session logical reads                                                           5800
     11256       5456
LATCH.cache buffers chains                                                            11554
     22563      11009
STAT...session pga memory max                                                         15104
         0     -15104
STAT...session pga memory                                                             77400
         0     -77400
STAT...table scan rows gotten                                                        412300
    824600     412300
* I have to use NDS to work around PLS-00103 error
* select count(*) from t;
  COUNT(*)
----------
      4123
Many thanks! 
 
January   24, 2003 - 6:13 pm UTC 
 
 
I don't know 
I don't know the tables you used
I cannot really read your input as it wraps and goes for page after page after page....
I can say the first one it more cpu intensive -- on a CPU challenged machine, it could tend to run slower. 
 
 
 
interprete runstats
Winston, January   24, 2003 - 6:57 pm UTC
 
 
From what you're saying I got the feeling that when we use runstat to compare two approaches...we should care more about "STAT...consistent gets"
and "STAT...session logical reads    "  then total elapse time. Please confirm.
I generated table t using the same way you used in the thread.
try sending the result again as below
423 hsecs
229 hsecs
run 1 ran in 184.72% of the time
PL/SQL procedure successfully completed.
> pause
> select a.name, b.value-a.value run1, c.value-b.value run2,
  2         ( (c.value-b.value)-(b.value-a.value)) diff
  3    from run_stats a, run_stats b, run_stats c
  4   where a.name = b.name
  5     and b.name = c.name
  6     and a.runid = 'before'
  7     and b.runid = 'after 1'
  8     and c.runid = 'after 2'
  9     and (c.value-a.value) > 0
 10     and (c.value-b.value) <> (b.value-a.value)
 11   order by abs( (c.value-b.value)-(b.value-a.value))
 12  /
NAME                                                                                   RUN1
-------------------------------------------------------------------------------- ----------
      RUN2       DIFF
---------- ----------
LATCH.session allocation                                                                  1
         0         -1
LATCH.undo global data                                                                    1
         0         -1
STAT...cluster key scans                                                                  2
         1         -1
STAT...cursor authentications                                                             0
         1          1
STAT...hot buffers moved to head of LRU                                                   2
         1         -1
STAT...opened cursors current                                                             3
         4          1
STAT...session cursor cache hits                                                        100
       101          1
STAT...free buffer requested                                                              3
         2         -1
LATCH.active checkpoint queue latch                                                       2
         0         -2
LATCH.redo writing                                                                        6
         4         -2
STAT...table fetch continued row                                                          2
         0         -2
STAT...parse time cpu                                                                     1
         4          3
STAT...redo entries                                                                      16
        13         -3
LATCH.redo allocation                                                                    15
        19          4
STAT...cluster key scan block gets                                                        2
         6          4
STAT...db block changes                                                                  27
        22         -5
STAT...session cursor cache count                                                         5
         0         -5
STAT...enqueue releases                                                                   7
         2         -5
STAT...enqueue requests                                                                   8
         2         -6
LATCH.enqueue hash chains                                                                12
         4         -8
LATCH.library cache load lock                                                            10
         2         -8
LATCH.messages                                                                           14
         5         -9
STAT...opened cursors cumulative                                                        119
       108        -11
LATCH.enqueues                                                                           24
         8        -16
STAT...rows fetched via callback                                                         18
         0        -18
STAT...execute count                                                                    133
       112        -21
STAT...calls to get snapshot scn: kcmgss                                                134
       112        -22
STAT...parse count (total)                                                              133
       108        -25
STAT...redo size                                                                      21524
     21480        -44
LATCH.checkpoint queue latch                                                             74
        27        -47
LATCH.row cache objects                                                                 126
        78        -48
STAT...buffer is pinned count                                                            49
         0        -49
STAT...table fetch by rowid                                                              80
        13        -67
STAT...table scans (short tables)                                                       100
       200        100
STAT...sorts (memory)                                                                   308
       204       -104
LATCH.shared pool                                                                       414
       250       -164
STAT...recursive cpu usage                                                              433
       235       -198
STAT...recursive calls                                                                  974
       701       -273
LATCH.library cache                                                                     855
       497       -358
STAT...db block gets                                                                    424
       817        393
STAT...sorts (rows)                                                                  827917
    826685      -1232
STAT...consistent gets                                                                 5376
     10439       5063
STAT...buffer is not pinned count                                                      5357
     10436       5079
STAT...no work - consistent read gets                                                  5276
     10423       5147
STAT...table scan blocks gotten                                                        5200
     10400       5200
STAT...session logical reads                                                           5800
     11256       5456
LATCH.cache buffers chains                                                            11555
     22562      11007
STAT...session pga memory                                                             25800
         0     -25800
STAT...table scan rows gotten                                                        412300
    824600     412300
49 rows selected.
 
 
January   25, 2003 - 11:01 am UTC 
 
 
need to teach you a simple command:
SQL> column name format a20
SQL> column run1 format 9999999
....
be really nice if your followup was about 1/4 of its current size (and readable)
LATCHES are what I look at most. 
Consistent gets -- sure, certainly.
CPU time can be very important as well -- something we are not seeing here.  For these two queries I would be tempted to use tkprof.  runstats is good for "approaches" (techniques), tkprof for queries.
Doing that on this and running each query 3 times we see:
select object_type
  from t
 group by object_type
having count(*) = ( select max(count(*))
                      from t
                     group by object_type )
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        3      0.00       0.00          0          0          0           0
Execute      3      0.00       0.00          0          0          0           0
Fetch        6      0.07       0.22          0       1108          1           6
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       12      0.07       0.22          0       1108          1           6
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 241
Rows     Row Source Operation
-------  ---------------------------------------------------
      2  FILTER
     25   SORT GROUP BY
  11439    TABLE ACCESS FULL T
      1   SORT AGGREGATE
     25    SORT GROUP BY
  11439     TABLE ACCESS FULL T
********************************************************************************
select object_type
  from ( select object_type, cnt, max(cnt) over () max_cnt
           from ( select distinct object_type,
                         count(*) over (partition by object_type) cnt
                    from t )
        ) where cnt = max_cnt
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        3      0.00       0.00          0          0          0           0
Execute      3      0.00       0.00          0          0          0           0
Fetch        6      0.13       0.21          0        552          0           6
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       12      0.13       0.22          0        552          0           6
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 241
Rows     Row Source Operation
-------  ---------------------------------------------------
      2  VIEW
     25   WINDOW BUFFER
     25    VIEW
     25     SORT UNIQUE
  11439      WINDOW SORT
  11439       TABLE ACCESS FULL T
So, as I said -- on a CPU challenged machine, the second query is somewhat MORE cpu intensive and this will show up as slower performance.
However, it does significantly less logical IO which is a bonus.
So -- it is a toss up.  Do you have some extra cpu power (seems you do not), the second might be a little more scalable as it will do less latching and such.  Are you CPU challenged?  the first might be more appealing. 
 
 
 
 
Best Practices
David, March     24, 2003 - 4:15 pm UTC
 
 
You make some very good points, as always.  I'd be interested to know if you have some SQL 'best practices' in terms of performance.  More than likely, "You shall use bind variables" is your #1 commandment.  I'm wondering if you have a Top Ten.  I'm sure you probably have a list that comes to mind for performance.  Some knowledgable people also have 'readability' best practices or 'robust coding' best practices.  For example, some might say that
insert into t1 select * from t2
is bad code because it's not explicit and if the order of the columns in the ddl ever changes, the results could vary.  I know that you're swamped with requests and you don't have time to write out 'proper' sql in asktom.com, so I'm not suggesting that you should be so precise, but if you saw that piece of code in an application, would you say it's fine the way it is? 
 
 
PL versus SQL
Gabriel, March     02, 2004 - 11:36 am UTC
 
 
Hello Tom,
I've been trying to convince my project manager that if I can do stuff in SQL is much better than doing them in PL/SQL. But he will have none of it. He thinks that an update will place row locks for far too long for him and make other transactions wait. I replied that PL can slow down his whole system if not needed etc. etc.
I then made a small test case using the runstats package that you developped. It is again obvious to me that the latches are serializable and on our env of 1000 concurrent connection that will have a big impact on scalability (as you can see I read your book ;-) ). But now I am at a loss to interpret some of the results of the runstats. Can you please help me with the ones that I didn't fill up and maybe correct me on the ones that I filled, or just send me a link where I can find the explanations (or both?).
exec runstats_pkg.rs_start;
declare 
x varchar2(20);
cursor c is
select substr(sapfile_row,0,(instr(sapfile_row,'|'))-1) cv from sapfile;
begin
for cv in c loop 
update hs_so_test hst 
   set XVUMATERIALSTATUS=                 
      (select ltrim(replace(substr(sapfile_row,(instr(sapfile_row,'|'))),'|',' '))info  
       from sapfile  
       where sapfile.SAPFILE_ROW not like ('HDR%')
       and
       sapfile.SAPFILE_ROW not like ('TRL%')
       and
       hst.WORKITEMID=x)
   where hst.workitemid  in (select substr(sapfile_row,0,(instr(sapfile_row,'|'))-1) from sapfile);
   commit;
end loop;   
end;
/
exec runstats_pkg.rs_middle;
update hs_so_test hst 
   set XVUMATERIALSTATUS=                 
      (select ltrim(replace(substr(sapfile_row,(instr(sapfile_row,'|'))),'|',' '))info  
       from sapfile  
       where sapfile.SAPFILE_ROW not like ('HDR%')
       and
       sapfile.SAPFILE_ROW not like ('TRL%')
       and
       substr(sapfile_row,0,(instr(sapfile_row,'|'))-1)=hst.WORKITEMID)
   where hst.workitemid  in (select substr(sapfile_row,0,(instr(sapfile_row,'|'))-1) from sapfile);
   
exec runstats_pkg.rs_stop(500);
   
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
0 rows updated.
Run1 ran in 50 hsecs
Run2 ran in 10 hsecs
Run1 ran in 500% of the time
    
Name                                Run1      Run2      Diff
STAT...session logical reads       1,442       789      -653
STAT...consistent gets               903       246      -657
LATCH.cache buffers chains         4,123     3,075    -1,048
STAT...table scan rows gotten      2,439       609    -1,830
STAT...sorts (rows)                5,715     3,878    -1,837
LATCH.row cache enqueue latch     25,130     5,028   -20,102
LATCH.row cache objects           37,670     7,537   -30,133
STAT...session pga memory              0   655,360   655,360
STAT...session uga memory              0 1,574,344 1,574,344
    
Run1 latches total versus runs -- difference and pct
Run1      Run2      Diff     Pct
68,759    17,052   -51,707 403.23%
PL/SQL procedure successfully completed.
session logical reads      :2 times more that current or other blocks were requested.
consistent gets            :3.5 times more the number of blocks that were requested. 
          
cache buffers chains       :???
table scan rows gotten     :4 times more the number of rows processed
sorts (rows)               :1.5 time more the number of rows sorted
row cache enqueue latch    :???
row cache objects          :???
session pga memory         :???
session uga memory         :???
Thank you very much, 
 
March     02, 2004 - 6:49 pm UTC 
 
 
cache buffers chains are latches we use to access blocks in the buffer cache (correlates well with your logical reads)
row cache latches protect the dictionary cache (shared definitions)
you would expect uga/pga memory to go up.  if you run again, they stay the same.  everything you do will "increase memory usage".