Home>Question Details



Raj -- Thanks for the question regarding "Rebuilding Indexes", version 5

Submitted on 28-Feb-2002 15:44 Central time zone
Last updated 1-Dec-2009 3:29

You Asked

I know this question has been asked earlier and 
I am sorry to take up this question slot but I
am confused regarding rebuilding indexes.

If I am interpreting it correctly, you don't
recommend rebuilding indexes at all. I have talked
to two seasoned Oracle dba's and they both
recommend rebuilding indexes at a regular period
of time. We have couple of tables with a million
to two million records but the indexes have never
been rebuilt. Also, we don't have that much 
deletion of records going on though we do have 
insertions and quite a few selects on those
tables. Do you recommend rebuilding indexes for
such a database.

What would be the implication if we did
have to rebuild the indexes. Would I need lot
of space for doing such a task.

Thanks a lot for your help.

Raj 

and we said...

Ask them for the technical reasons WHY they rebuild.

When they say "performance of course" -- ask them for the performance metrics they took 
BEFORE the rebuild and AFTER the rebuild.  They won't have any (no one ever does, no one 
seems to think about doing that).  They will say "it just goes faster trust me".  

When they say "to reclaim space of course" -- ask them "but how long does it take before 
the index is just a big as it was before the rebuild".  You see they have not reclaimed 
any space -- the index will just grow again, eventually hitting a steady state size that 
it likes to be.  

If you need to rebuild your indexes, you need 2x the space -- you'll have the old and the 
new index for a period of time.  If you do it online, you'll need additional space to 
hold the changes that are made during the rebuild as well. 

Reviews    
3 stars Is your advice against rebuilding a "blanket" one?   March 1, 2002 - 10am Central time zone
Reviewer: Mohit Dubey from UK
Hi Tom,

Would rebuilding indexes not help in case you want to re-balance the b*tree? Particularly in case 
of indexes deriving their values from a monotonically increasing sequence (as I trust most of the 
unique/foreign keys are)?

Please throw some more light on this issue!

Mohit. 


Followup   March 1, 2002 - 1pm Central time zone:

If you can show me mearsurable performance increases or some other measurable, material benefit -- 
by all means rebuild.

99.99999999% of the time, no one measures, they just rebuild everything (making a really big deal 
out of it, wasting time, cutting off access, generating overtime hours, etc....

To HAVE to rebuild it a rarity -- not the norm.  Keep good metrics, show the before and after 
effects.  Be ready to prove that the rebuild was worth the effort (i mean, we have to benchmark 
ourselves in so many other ways -- why is this any different).

 

3 stars Rebuilding Indexes   March 1, 2002 - 2pm Central time zone
Reviewer: Rob from Chicago
I find that I have to watch bitmap indexes very closely.
Our fact tables get loaded every day and every so often a bitmap index seems to grow very rapidly. 
I rebuild the index and it then holds at a steady state. I see this often if we delete and reinsert 
a days worth of info. The performance improvements comes for the inserts on the table not the 
select using the index. 

 


Followup   March 1, 2002 - 2pm Central time zone:

Agreed -- bitmaps are a special case, easily measurable, definite payback.

Now, about b*trees......  

5 stars online index rebuild   February 24, 2004 - 12pm Central time zone
Reviewer: reader 
Doc says that when we rebuild index online, the changes are allowed and they are stored in a 
"journal table". What happens to the changes in the journal table if the rebuild aborts for some 
reason after i started the index rebuild? Are they lost?  Thanks. 


Followup   February 24, 2004 - 1pm Central time zone:

they are cleaned up for you.

they are not "lost", they are "not useful anymore" if the rebuild aborts.

You would just start the rebuild again and start journaling anew -- no need for the old stuff, it 
would be counter productive to attempt to use it. 

5 stars index and table in the same tablespace   February 24, 2004 - 5pm Central time zone
Reviewer: reader 
From 
http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96521/indexes.htm#310
<quote>Using different tablespaces (on different disks) for a table and its index produces better 
performance than storing the table and index in the same tablespace. Disk contention is reduced. 
<quote>

Tom, is the above still recommended? Thanks. 


Followup   February 25, 2004 - 7am Central time zone:

no

 

4 stars index hijacking   February 24, 2004 - 7pm Central time zone
Reviewer: VKOUL from Lacey, WA USA
Hi Tom

Pls. go through the following

SQL> create table abc (x number);

Table created.

SQL> create index abc_non_unique_idx on abc(x);

Index created.

SQL> insert into abc values (1);

1 row created.

SQL> insert into abc values (1);

1 row created.

SQL> select * from abc;
Press Enter ...

         X
----------
         1
         1

SQL> roll
Rollback complete.
SQL> 
SQL> select * from abc;

no rows selected

SQL> @1.lst

                    INDEX_NAME : ABC_NON_UNIQUE_IDX
                    INDEX_TYPE : NORMAL
                   TABLE_OWNER : VKOUL
                    TABLE_NAME : ABC
                    TABLE_TYPE : TABLE
                    UNIQUENESS : NONUNIQUE
                   COMPRESSION : DISABLED
                 PREFIX_LENGTH :
               TABLESPACE_NAME : USERS
                     INI_TRANS : 2
                     MAX_TRANS : 255
                INITIAL_EXTENT : 1048576
                   NEXT_EXTENT : 1048576
                   MIN_EXTENTS : 2
                   MAX_EXTENTS : 2147483645
                  PCT_INCREASE : 0
                 PCT_THRESHOLD :
                INCLUDE_COLUMN :
                     FREELISTS : 1
               FREELIST_GROUPS : 1
                      PCT_FREE : 10
                       LOGGING : YES
                        BLEVEL :
                   LEAF_BLOCKS :
                 DISTINCT_KEYS :
       AVG_LEAF_BLOCKS_PER_KEY :
       AVG_DATA_BLOCKS_PER_KEY :
             CLUSTERING_FACTOR :
                        STATUS : VALID
                      NUM_ROWS :
                   SAMPLE_SIZE :
                 LAST_ANALYZED :
                        DEGREE : 1
                     INSTANCES : 1
                   PARTITIONED : NO
                     TEMPORARY : N
                     GENERATED : N
                     SECONDARY : N
                   BUFFER_POOL : DEFAULT
                    USER_STATS : NO
                      DURATION :
             PCT_DIRECT_ACCESS :
                    ITYP_OWNER :
                     ITYP_NAME :
                    PARAMETERS :
                  GLOBAL_STATS : NO
                 DOMIDX_STATUS :
               DOMIDX_OPSTATUS :
                FUNCIDX_STATUS :


SQL> 
SQL> alter table abc add constraint pk_abc primary key
  2  (x) using index;

Table altered.

SQL>  insert into abc values (1);

1 row created.

SQL> /
 insert into abc values (1)
*
ERROR at line 1:
ORA-00001: unique constraint (VKOUL.PK_ABC) violated


SQL> 
SQL> @1.lst

                    INDEX_NAME : ABC_NON_UNIQUE_IDX
                    INDEX_TYPE : NORMAL
                   TABLE_OWNER : VKOUL
                    TABLE_NAME : ABC
                    TABLE_TYPE : TABLE
                    UNIQUENESS : NONUNIQUE
                   COMPRESSION : DISABLED
                 PREFIX_LENGTH :
               TABLESPACE_NAME : USERS
                     INI_TRANS : 2
                     MAX_TRANS : 255
                INITIAL_EXTENT : 1048576
                   NEXT_EXTENT : 1048576
                   MIN_EXTENTS : 2
                   MAX_EXTENTS : 2147483645
                  PCT_INCREASE : 0
                 PCT_THRESHOLD :
                INCLUDE_COLUMN :
                     FREELISTS : 1
               FREELIST_GROUPS : 1
                      PCT_FREE : 10
                       LOGGING : YES
                        BLEVEL :
                   LEAF_BLOCKS :
                 DISTINCT_KEYS :
       AVG_LEAF_BLOCKS_PER_KEY :
       AVG_DATA_BLOCKS_PER_KEY :
             CLUSTERING_FACTOR :
                        STATUS : VALID
                      NUM_ROWS :
                   SAMPLE_SIZE :
                 LAST_ANALYZED :
                        DEGREE : 1
                     INSTANCES : 1
                   PARTITIONED : NO
                     TEMPORARY : N
                     GENERATED : N
                     SECONDARY : N
                   BUFFER_POOL : DEFAULT
                    USER_STATS : NO
                      DURATION :
             PCT_DIRECT_ACCESS :
                    ITYP_OWNER :
                     ITYP_NAME :
                    PARAMETERS :
                  GLOBAL_STATS : NO
                 DOMIDX_STATUS :
               DOMIDX_OPSTATUS :
                FUNCIDX_STATUS :


SQL> 
SQL> disconnect
Disconnected from Oracle8i Enterprise Edition Release 8.1.7.3.0 - 64bit Production
With the Partitioning option
JServer Release 8.1.7.3.0 - 64bit Production
SQL> 


Q1 : How does Oracle implement uniqueness, since the underlying index is NONUNIQUE ? Does Oracle 
recreates index on primary key creation, if that is so, why in index data it says it is NONUNIQUE ?

Q2 : On your site I have read somewhere like "There is no nonunique B*tree, in case of non-unique 
indexes, the rowid is concatenated with the value to make it unique". In this case does it 
segregate rowid from the value after hijacking ?

Q3 : What effect does it have on optimizer in selecting a plan.

Thanks 


Followup   February 25, 2004 - 8am Central time zone:

q1) it doesn't matter "how", only that it "does" at the end of the day.

Since version 8.0 with deferrable constraints, we've only needed AN INDEX to enforce uniqueness.  
Not a unique index, just an index.

q2) not relevant to us.  only relevant that "it works".  the internal mechanics, not known to us.  
all we need know is a primary key/unique constraint will

a) look for the columns to be on the leading edge of any index, if found, use it, consider:


ops$tkyte@ORA920PC> create table t ( x int, y int );
Table created.
 
ops$tkyte@ORA920PC> create index t_idx on t(x,y);
Index created.
 
ops$tkyte@ORA920PC> alter table t add constraint t_pk primary key(x);
Table altered.
 
ops$tkyte@ORA920PC> select index_name from user_indexes;
 
INDEX_NAME
------------------------------
T_IDX
 
ops$tkyte@ORA920PC> drop index t_idx;
drop index t_idx
           *
ERROR at line 1:
ORA-02429: cannot drop index used for enforcement of unique/primary key

b) if not found and constraint is not deferrable, create unique index by default
c) if not found and constraint is deferrable, create non-unique index by default

q3) nothing horribly measurable really.  It would be rare for it to affect a plan, in light of 
statistics, the optimizer will understand about how many rows (1) would come back based on "where 
pk = value".  That and remember -- indexes are the tuning tools here.  If you needed a unique index 
for performance reasons, then you most certainly should not have created a non-unique one.  


 

4 stars Interesting...   February 25, 2004 - 8am Central time zone
Reviewer: Invisible from UK
<reader>
Should indexes go in a separate tablespace to tables?
</reader>

<Tom>
No.
</Tom>

...any reason WHY this should be so? Just curiouse...
 


Followup   February 25, 2004 - 9am Central time zone:

in the olden days....


before logical volumes
before striping
before 500+ table schemas 

when you had like 10 tables and 12 indexes and a couple of disks direct attached....


putting indexes on one and data on the other was an attempt to evenly distribute IO over both 
devices.  "couple of index reads - many from cache, one or so from disk" followed by "table access 
by index rowid" maybe from cache, maybe not -- would tend to put 1/2 the IO on each of your two 
disks.

The SAME effect could have been achieved by using really small extents and making sure each object 
was in 100 or so extents -- the data would have been nicely striped (but that ran counter to that 
extent myth so no one did that)...


Today with 5000 objects in a schema, gigabytes/terabytes of storage, raid striping, logical volumes 
-- it just isn't relevant in the least.  


Me, I use tablespaces to hold application when appropriate.  Your application will get A tablespace 
unless your application has some really large tables.  Then and only then will we carve out extra 
things to manage. 

5 stars Cool.   February 25, 2004 - 10am Central time zone
Reviewer: Invisible from UK
Thanks for that Tom. :-)

I presume from the above that there's also no particular PROBLEM if the DB is already set up with 
everything separated out?
 


Followup   February 25, 2004 - 11am Central time zone:

nope, just extra stuff to manage.

use tablespaces as an administrative/bookeeping tool, not so much as a tuning device. 

5 stars Not rebuild index definitively?   February 25, 2004 - 10am Central time zone
Reviewer: A reader 
Hi Tom,

What do you think about rebuild index yearly,
or the answer is definitively 
NO index rebuild necessary, unless something like block corruption in index or other rarity like 
this.

Thanks 


Followup   February 25, 2004 - 11am Central time zone:

I do not beleive in a scheduled rebuild of indexes.


I do believe in 

a) determining the root cause of a performance related issue
b) correcting it

and if part of b) is rebuilding an index, so be it.  but to rebuild on a schedule?  No. 

5 stars   February 25, 2004 - 11am Central time zone
Reviewer: A reader 
Thanks Tom,
 


3 stars Rebuilding online reply   February 25, 2004 - 12pm Central time zone
Reviewer: Steve from Midwest
Just to clarify one point to your reply to the question:

"What happens to the changes in the journal table if 
the rebuild aborts for some reason after i started the index rebuild? Are they lost?"

You reply they are cleaned up for you...  I guess the documentation may say that is the case but 
we've ran into various issues with both 8i and 9i where the journal table does not get dropped 
under certain conditions and future attempts to rebuild the index (or analyze the table) require 
intervention.  In 8.1.7.2 if a session is killed rebuilding an index we had to go out there and 
update ind$ to get the index status out of "rebuild" status along with manually dropping the 
journal table.  In 9.2.0.3 if a session is killed or you ctrl c out of the rebuild or you get an 
unable to extent message you need to manually drop the journal table in order to rebuild it online 
after the "abort".  I'm sure there's other conditions that cause problems but this is just a 
couple.

Just want to highlight this feature is a bit buggy if various conditions are hit. 


5 stars   May 14, 2004 - 12pm Central time zone
Reviewer: A reader 
Hi Tom could you give your opinion please about this paper
http://www.actoug.org.au/Downloads/oracle_index_internals.pdf
Because I'm still investigating if there are really situations when you need to rebuild the index

Specially about 
 &#8220;If the index clustering factor is high, an index
rebuild may be beneficial&#8221; Don Burleson: Inside
Oracle Indexing dated December 2003 at
www.DBAzine.com

Thank you 


Followup   May 15, 2004 - 11am Central time zone:

I loved it -- already read it.  loved it.

perfect.


The one about clustering factor is PARTICULARLY AMUSING isn't it?

the cluster factor is the number of LIOs against the table that would be performed as we range scan 
through the index.  If we are range scanning and the first 15 index elements all point to the same 
block, that would be 1 LIO.  On the other hand, if the 15 index elements all point to DIFFERENT 
blocks, that would be 15 LIO's...

So, if a table is sorted in the same key order as the index, the cluster factor will be very near 
the number of blocks in the table.

If a table is not sorted as the index is, the cluster factor will be near the number of rows in the 
table.


So, tell me -- how could rebuilding an index affect the cluster factor since the cluster factor is 
a metric based on the TABLE not the index????

How can reorging an index affect a metric that has nothing to do with the structure of the index?  

A table rebuild -- sorting the table by the index key columns -- now that would lower the cluster 
factor of that index but destroy the cluster factor of the other indexes since a table can be 
sorted in about 1 way...

I loved that presentation.



Yes, there are times when an index rebuild can be beneficial.
Yes, there are times when an index rebuild can be harmful.
No, there are no times when a scheduled rebuild of all indexes is "good".


Rebuilding an index just "because it might be the cause of some issue" is a fairly 
"non-professional" thing to do.  Sort of like a police officer sticking his hand into a dark room 
and shooting a gun, hoping to kill the bad guys.  Problem is, there are good guys in the room too.  
You might hit them, you might get the bad guy -- but hit 2 good guys on the way as well.


Lets say you goto the doctor and give them your list of symptoms.  Instead of performing a test, 
diagnosing your case, they say "you know, I've given this medicine to lots of people in the past 
and it helped some of them.  why don't you try this and tell me what happens first."  

Would you use that doctor?  Or would you want them to be fairly certain of what was wrong before 
prescribing a treatment, or have them prescribing a treatment that while it works -- causes other 
side effects you would rather not have?  (I can fix your broken leg by amputation or by setting it 
-- which would you pick given the choice?)





 

5 stars choose your authors carefully ...   May 15, 2004 - 1pm Central time zone
Reviewer: Alberto Dell'Era from Milan, Italy
My 2 cents from my book/whitepaper addiction experience - read only informations published by 
reputable authors (who are NOT necessarily the ones that wrote best-selling books).  

"Guru suggestions" such as the one above almost destroyed my Oracle career (and especially 
motivation!) - so now I read almost exclusively material by 3 or 4 authors that I've learnt to be 
trustable and professional.

Interestingly, the aforementioned trustable authors ALL belong to the OakTable network - but at 
least two of them had been in my deja query well before the OakTable was born :) 


5 stars   May 15, 2004 - 7pm Central time zone
Reviewer: A reader 
Thanks Tom 


5 stars Oracle's B-Tree index is always balanced. Always.   August 21, 2004 - 2am Central time zone
Reviewer: Oracle DBA from Bombay, India
I am a bit more curious about Oracle’s implementation of B-Tree indexes. When its said that 
“Oracle's B-Tree index is always balanced. Always.” Does it mean that if I have 3 records in the 
index then 2 will be the root node and 1 and 3 will be left and right respectively and when 4 more 
records added to the index then 4 will “automatically” become root node with 2 and 6 in its left 
and right and so on?
I went thru the pdf link given by A reader on May 14, 2004 which described index structure as 
sorted liner “leaf” data with branch / parent block stores the data related to starting point of 
its left and right / child [ may be more than 2 ] nodes. 
My question is - will the “tree” build on top of these leaves data be automatically altered so that 
it will be balanced ALWAYS?
Thanx a ton Tom almighty. 


Followup   August 21, 2004 - 12pm Central time zone:

it means the height of the leaf nodes for all leaves is consistent.

if one leaf node is at level "2", ALL leaf nodes are at level "2"

it would take two IO's to get to ANY leaf node.

it would be unbalanced if some leaf nodes took 3 LIO's, some 4 and some 2.  

If one leaf is at level 4, all leaves are.


if there were only 3 index entries, in all probability there would only be a single leaf block 
(which would also be the root block which would also be the branch block).

 

4 stars Growth of Index "Tree"   August 21, 2004 - 3pm Central time zone
Reviewer: Oracle DBA from Bombay, India.
Let me know if my understanding is wrong. When data is added to base table and if this insert 
requires new branch block then rather than creating child node it will create a peer node and also 
a parent node to store starting point of its children nodes. i.e. it grows from bottom to top 
instead of conventional top down growth.
For eg consider each leaf can contain 2 indexed column records with its respective rowid. Then 
first 4 records can be accessed with only 1 root / block node and 2 leaves node. Like below

1
3

1  <->  3
2       4

when 5th row is inserted in the table it will create another leaf and also a peer to the block node 
and also a parent to the peers like

1
5

1               5
3

1  <->  3  <->  5
2       4

with 1 as root node 2 branch nodes and 3 leaf nodes.

Now consider first 8 records inserted into table; skipping 4 which will create an index structure 
as below.

1
6

1               6
3               8

1  <->  3  <->  6  <->  8
2       5       7       9

which is a complete / fully utilized b-tree. Pls. let me know if above demonstrated details are 
true or not and if yes then what will happen if a row with id as 4 is inserted in the table.
 


Followup   August 21, 2004 - 3pm Central time zone:

the branches may have many many many entries, this is not a simple "b-tree" with left and right -- 
this is a fairly complex structure.

for some details- see the CONCEPTS guide (most important document you'll ever read) or "Expert one 
on one Oracle" -- I cover the structure in there with pictures and what not. 

3 stars Don Burlescon "New Oracle Myth: Index rebuilding requires careful analysis"   September 7, 2004 - 6am Central time zone
Reviewer: Jens Bob from Walton Mountains
Hi Tom,

have you read Don Burlescons article on DBAZINE: 

http://www.dbazine.com/burleson25.shtml
What is your opinion about his "Myths" and about the whole article?
 
Bye,

Jens 


Followup   September 7, 2004 - 9am Central time zone:

Yes I read it.  

Nice graphs.  They are pretty. 

5 stars That sounds like "Forget, what Don wrote"   September 7, 2004 - 9am Central time zone
Reviewer: Jens Bob from Walton Mountain
I would ask them how he got the title "one of the world’s top Oracle Database experts". 

It's not easy to get an in-depth knowlegde of Oracle, if every "expert" tell different things. 

>>>
Donald K. Burleson is one of the world’s top Oracle Database experts with more than 20 years of 
full-time DBA experience. He specializes in creating database architectures for very large online 
databases and he has worked with some of the world’s most powerful and complex systems. A former 
Adjunct Professor, Don Burleson has written 15 books, published more than 100 articles in national 
magazines, serves as Editor-in-Chief of Oracle Internals and edits for Rampant TechPress. Don is a 
popular lecturer and teacher and is a frequent speaker at Oracle Openworld and other international 
database conferences. Don’s Web sites include DBA-Oracle, Remote-DBA, Oracle-training, remote 
support and remote DBA.
<<< 


5 stars "experts"   September 7, 2004 - 9pm Central time zone
Reviewer: Reader from Aus
I'm sure DB is an "expert" based on the definition:

- experts CLAIM things
- scientists PROVE things

I'd much rather be a scientist 


Followup   September 8, 2004 - 8am Central time zone:

Yes, I would have personally preferred to see some hard facts in there instead of "I've seen this 
happen before, not sure why...."

For example:

1. When a index rebuild is combined with a table reorganization (using the dbms_redefinition 
package). This is especially useful when the data is accessed via index range scans and when the 
table is re-sequenced into index-key order (using single-table clusters, or via a CTAS with an 
order by clause).


I would ask some of the following questions:

o when would an index rebuild NOT be combined with a table reorg? 

o how many actual case studies has the author done with dbms_redefinition using 
  the brand new orderby_cols feature of 10g in the real world? (in 9i, you 
  could not sort the rows using dbms_redefinition).  Are there any serious
  performance implications of these online operations one needs to be concerned
  with?

o CTAS is an offline operation -- cannot allow modification DML to the original
  table -- so you propose to make my Oracle database unavailable on a recurring
  basis (note: this is my main issue with scheduled full reorgs.  people tend
  to a) not use online, b) schedule them frequently, c) tell people "well 
  Oracle cannot do this Mr. Mgr, so yes, your systems are offline because of 
  the software". )

o why not suggest the permanent solution -- you almost seem to hint sort of at
  it by mentioning "single table <hash> clusters" but what that would do 
  for data that is accessed "in a range scan" is beyond me.  Since "single 
  table" clusters are exclusively hash clusters and hash clusters do not (by
  definition) support range scanning by the hash key, I'm left in a state of
  confusion as to what that reference could be pertaining to

o but the real solution for data like this would or could be "IOT".  If you 
  find that you frequently
   a) have to CTAS with order by or
   b) in 10g use dbms_redefinition with the order by option
   c) and rebuild indexes because A and B force you too

  why not use dbms_redefinition (9i or 10g) to rebuild the object into an IOT
  that will preserve the sorted order natually for you over time?  Do it once,
  and fix the root cause.

o how do I measure and report to my mgmt the benefits accrued by these
  expensive, ongoing operations (by expensive, I'm refering to either the 
  scheduled offline rebuild -- CTAS, or the "not totally for free" implications
  of an online rebuild.


Those are the sorts of things I'd need to see for someone to show me "myth busting" I guess.


I'd also look at:

2. When a heavily-updated index is rebuilt. In highly volatile databases in which table and column 
values change radically, periodic index rebuilds will reclaim index space and improve the 
performance of index range scans.

so show me?  show me how to measure that.  Show me WHEN it makes sense (define what you mean by 
heavily updated).  Will the space reclaimation be permanent or will the index rapidly get fat 
again?  If my redo jumps by an factor of two or three in the days immediately following this 
operation - might there be a tie in?  What is the cost of doing this -- I mean, if the index wants 
to be "fat" -- and we make it "skinny" -- how long till it gets fat and again, and to carry the 
analogy to an extreme -- is making an index skinny/fat/skinny/fat over and over again as bad for 
it's overall health as it is for humans that bounce their weight back and forth frequently (quite 
stressful for the body).  To what end is this magic "space reclaimation" if the index is just going 
to need it again next week (I mean it isn't like it is going to wise to reuse that space for 
something else right?).

Actually, a heavily modified index -- where the entries fly around -- would be one I don't want to 
rebuild - that index took lots of work to get to its relatively "fluffy" state with just enough 
whitespace in the interior to accomidate the movement of key entries *WITHOUT EXPENSIVE INTERNAL 
INDEX OPERATIONS*.


<quote>
In the real-world, Oracle professionals will occasionally schedule index rebuilds during off-hours, 
knowing that the worst possible scenario is that there is no space reclamation or performance 
improvements.
</quote>

"knowing that the worst possible scenario includes"

o larger than normal redo generation in the days to come.

o increased (yes, increased) space utilization (how so?  ask yourself, so when does pctfree come 
into play for an index, what might pctfree do to a well packed right hand side index?)

o  





I LOVE the index article he points to, contains awesome facts I was never aware of till now, such 
as:

o Oracle indexes are not self-balancing. 

o When a row is deleted from a table, the Oracle database will not reuse the corresponding index 
space until you rebuild the index

o Therefore, indexes are always growing and can become very fragmented over time

o This node could spawn a fourth level without the other level-three nodes spawning new levels. 
That makes the index unbalanced.

o An index could have 90 percent of the nodes at three levels, but excessive splitting and spawning 
in one area of the index with heavy DML operations could make nodes in that area to have more than 
three levels.


and oh, it gets better as it goes on.  Sage advice such as "del_lf_rows should be less than 20% of 
the total", "if index height >= 4, rebuild" and under the heading of "Amazing Results"  
 

I would encourage everyone to take a peek at

http://www.actoug.org.au/Downloads/oracle_index_internals.pdf
it is really nicely presented and even includes a number or two. 

5 stars Expert ?   September 8, 2004 - 8am Central time zone
Reviewer: A reader 
When experts claim things, they're usually correct.

When Mr Burleson claims things, they're usually wrong.

The person who wrote that article is not an Oracle expert, no matter the definition. 


5 stars Index Rebuilds - Proof   September 8, 2004 - 9am Central time zone
Reviewer: Tony Andrews from London, UK
In another of his own articles that he links to - 
http://www.dbazine.com/burleson18.shtml
- Don Burleson says:

"To date, none of the world’s Oracle experts has determined a reliable rule for index rebuilding, 
and no expert has proven that index re-builds “rarely” help."

Yet again and agin, he fails to prove that they DO help.  All he ever offers is anecdotal evidence 
like "I have seen cases in which performance radically improves after an index rebuild".  He even 
admits that the perceived improvement may be no more than the "placebo effect".

Surely if someone is selling medicine that claims to cure baldness, the onus is on him to prove it 
works, not on others to prove that it does not?  After all, however many benchmark examples someone 
like you could come up with that show no improvement, he can still say "ah, but I have seen other 
cases where it did, so there".  

Surely it should be possible for Mr Burleson to construct a test case that proves his point?  
Assuming it CAN be proved that is... 


Followup   September 8, 2004 - 10am Central time zone:

http://www.computerworld.com/departments/opinions/sharktank/0,4885,95744,00.html
someone emailed me that link this morning.

somehow, just somehow, it seems appropriate. 

5 stars that ACTOUG presentation looks impressive....   September 8, 2004 - 11am Central time zone
Reviewer: Mike Stone from Liverpool, UK
...well argued, with examples to back up the assertions. I've taken a copy for closer study.

In passing - and by contrast - what do you make of figure 2 in DB's DBAzine article!?

Leaving aside the meaningless reference to the "second derivative" of an undefined mathematical 
function "f(x)", in what way does the graph illustrate how the optimal setting for db_cache_size is 
arrived at? 


Followup   September 8, 2004 - 1pm Central time zone:

the only thing that graph shows is the estimated Physical IO that would performed given a cache 
size of X.

Why is that point the "optimal" point?  Seems if I had 50 gigawads of memory that I wasn't using, 
the optimal point would be further left?

At the end of the day -- there are many ways to fix problems.  The "Automatic" stuff looks at 
metrics and based on rules -- says go do this, add ram.  Great, perfect.  What if -- you don't have 
it?  What if -- you could tune a query.  You know what is missing on that picture -- on that page?  
It could be perhaps the SQL Tuning session that says "hey, add an index and your IO on this query 
will go from 1,000,000 to 4".  Might that - just might that - perhaps, maybe slightly impact your 
performance?  

For example, take a look at:

http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:9843506698920#23327315081899
No matter HOW WELL the database cached my data -- no matter how well or fast -- the "solution" is 
the last query.  The problem that could be fixed a little bit (not all of the way, just a nudge the 
left) was a full scan of a table.  We could make that a fast full scan of an index (better).  The 
real answer -- look at the problem and fix it.  

Now, the pretty graphic would be totally different wouldn't it.

Yes, playing with the buffer cache can have a material affect on response time.

Yes, playing with the algorithms -- the implementation -- is by far going to have the most MASSIVE 
impacts.



And another interesting bit of food for thought is

"If the machine can do this (ratio based tuning), do I as a human being really need to also be 
doing it -- or is the machine better at it than I am.  Perhaps I as a human being can spend my time 
adding value elsewhere, doing the things that transcend what the machine can figure out all by 
itself"

 

5 stars avoid that TOP 'Expert'   September 8, 2004 - 11pm Central time zone
Reviewer: Winston 
I have recommended people to read Tom's books and Oracle docs instead. 


5 stars Liked the computerworld article   September 10, 2004 - 10am Central time zone
Reviewer: A reader 
that was funny! 


Followup   September 10, 2004 - 10am Central time zone:


5 stars Whats the matter with the experts   September 15, 2004 - 5pm Central time zone
Reviewer: subbu from MN, USA
I was reading 
http://searchoracle.techtarget.com/tip/0,289483,sid41_gci1006334,00.html?track=NL-93&ad=491728
and thought of looking for what Tom has to say on this because somehow i was getting a feeling that 
it talks about the tuning help which i refer at this asktom site and searched for "Donald K. 
Burleson" in asktom.oracle.com.
I quickly got reference to this one article.
What is right? and whats the matter with the experts?
i'm left confused.
BTW -
http://www.computerworld.com/departments/opinions/sharktank/0,4885,95744,00.html
 article helps in identifying the air-conditioning problem my office room is facing. 


Followup   September 15, 2004 - 9pm Central time zone:

it would have been very interesting if DKB's article of "tips" actually provided useful information 
like "how to do this stuff".

I found nothing "actionable" in that article (searchoracle) -- no advice on how to actually *do 
anything*.  Just rambling on as to how a scientific approach (actually discovering what the problem 
is) is "bad".  it seems to boil down to

o increase your buffer caches
o add cpus
o upgrade your network
o buy a new disk subsystem

rather than

o diagnose the issue, find the root cause
o fix it.

for example he says:

Fallacy: The sole purpose of Oracle tuning should be to reduce logical I/O

I'm not aware of anyone that has said "the sole purpose".  When asked "hey, I want to tune, where 
should I start", many reasonable people say "well, look for the high load SQL, that would be SQL 
with lots of consistent gets/ execution. Lets look at seeing if perhaps an index, the use of 
analytics, better physical design, an IOT, a materialized view might help"

He says:

"Accessing Oracle data via the data buffers is at least 10x faster (sometimes hundreds of times 
faster) than disk access, so one should not"....

throw more RAM at it.  Me, adding RAM is the last step after diagnosing the issue.  Be a pity 
to buy that new airconditioning unit if all you needed was cardboard :)



He says:

Fallacy: Hourly tuning averages are meaningless

which I believe to be true (a 15/30 minute observation -- taken on the hour - whats wrong with 
that?) is useless as a *tuning* device, but extremely useful as a method to see "whats changed" 
(thats what we use it for).  I think I wrote in both of my books that "you need to take statspacks 
in sickness and in HEALTH, trying to use them to tune a system *without having them from before, 
when the 'system' was good* is, well, like reading tea leaves.  

but if you had them from when things are good -- awesome, compare them, trend them, see what 
"changed"

tuning -- no
finding out "something has changed and this is what changed" -- yes.



He says:

Fallacy: Only transaction-level tuning will be successful

.... System-level tuning is a reality. Some tuning professionals treat the system-wide issues first 
and then drill-in to the sub-optimal PL/SQL and SQL. Other shops that do not have the large 
amount of funds required to pay for detailed application-level changes (tweaking application code 
& SQL). Here are some examples of real-world system-level Oracle tuning activities:

o Replace sub-optimal RAID - (he says to replace your disk subsystem, that'll save tons of money 
won't it, this is followed up by another bullet point suggesting raid 0+1 or even that inexpensive 
solid state disk)

o Change sub-optimal optimizer parameters - Resetting a sub-optimal setting for several optimizer 
parameters (optimizer_mode, optimizer_index_cost_adj) can double the performance of some systems. 
Changing optimizer_mode=rule to optimizer_mode=first rows (or vice-versa sometimes!) can influence 
the performance of every SQL statement in the application (so, any ideas for us here, any advice? 
 or should we just guess -- close our eyes and shoot the gun into the other room and see if we 
accidently hit any bad guys?  Thing is the last sentence sort of understates it -- these settings 
will influence the performance -- not can, will)

o Fix poor-quality optimizer statistics - The Oracle cost-based SQL optimizer (CBO) will only make 
good decisions if it has good-quality samples from the schema objects. (i'm curious -- how do you 
KNOW you have bad stats at the system level, unless you've identified bad sql that has really off 
cardinalities -- that is what tells you "bad stats".  i'm really curious how "system level stats 
pack" would point to "stats are bad")

o Use a faster network (hmmm, no comment on that one.  I always say "use the fastest of 
everything you can get -- but sure, we'll throw out our network infrastructure and replace it -- 
tomorrow.  It'll definitely be faster and cost less then, oh, i don't know, looking at an 
application?)

o Get faster processors - Faster (or more) CPUs may greatly improve performance of Oracle system 
that are constrained by CPU (right in that "cheaper, faster, better mantra - dig it.  Oh, and you 
can just point click and ship that right?  and -- you've never seen a 16 cpu machine get upgraded 
to 32 and simply "fall over" (it was 100% utilized at 16 -- massive latch contention, guess what 
happened when we gave it more cpu.... maybe we should have fixed the hard parse problem instead -- 
must be sounding like a broken record, it all comes back to parsing doesn't it?)


He says:
Fallacy: If an Oracle tuning metric has an exception, it is not valid

and we've said "a metric by itself is not always useful.  Just because it is 99%, does not mean 
*GOOD*.  50% might mean "bad" but a high value does not mean "good" -- it just means maybe ok -- 
you have to look elsewhere if you want to see if you are "good".


In a tuning tips sort of thing, it would have been nice to have something actionable, something 
with a number or two.  And if one is going to point to "them" -- one might want to point to 
referenceable quotes, sort of in the manner of

http://www.actoug.org.au/Downloads/oracle_index_internals.pdf

(excellent paper, love it more each time I read it) 

5 stars Index Fragmentation ?   September 16, 2004 - 6am Central time zone
Reviewer: Nilanjan Ray from India
Hi Tom,

Excellent discussions. Shakes off quite a few deep rooted myths. I don't mean to irritate you 
further with my questions. But an explanation/corrections in your usual witty manner :) would be 
most helpful.

1. An indexed column undergoing heavy deletes would actually leave a large value for DEL_LF_ROWS in 
NDEX_STATS, leading to a large number of sparsely poulated leaf blocks. Therefore during an index 
range scan it will involve more IO against the index, decreasing performance ( this is eactly where 
I need your opinion). Afer a rebuild
DEL_LF_ROWS drops to zero, reducing the IO on the index and thereby improves performance, though 
temporarily( eventually,as you rightly say the index would assume its own *stady state*). 
2. Redo generation increases after index rebuild. Is it due to the fact that "branch block 
splitting" occurs in the process of attaining its *good old steady state* ?
3. People have been using DEL_LF_ROWS and LF_ROWS to measure index fragmentation, eventually 
leading to an index rebuild. If rebuild is of little or no use in the long run, can you point out 
what useful information/analysis/conlusion can we draw out of DEL_LF_ROWS column in INDEX_STATS?

Thanks in advance 

Regards
Ray  


Followup   September 16, 2004 - 9am Central time zone:

1) if you heavily delete -- and never ever insert or update, this MIGHT hold water - if we actually 
always left deleted leaf rows there (we don't).

consider this table:

drop table t;
create table t ( x int, y char(20) default 'x' );
drop sequence s;
create sequence s;
alter table t add constraint t_pk primary key(x);
                                                                                                    
                

Ok, I set up one pro*c program doing nothing but this:

void process( int rows )
{
int  i;
                                                                                                    
                
    EXEC SQL WHENEVER SQLERROR DO sqlerror_hard();
    for( i = 0; i < rows; i++ )
    {
        exec sql insert into t (x) values ( s.nextval );
        exec sql commit;
        if ( i%1000 == 0 )
            printf( "inserted row %d\n", i+1 );
    }
    exit(0);
}


and another to do this:

void process( int rows )
{
int  i;
                                                                                                    
                
    EXEC SQL WHENEVER SQLERROR DO sqlerror_hard();
    for( i = 0; i < rows; i++ )
    {
        exec sql delete from t where x = (select min(x) from t);
        exec sql commit;
        if ( i%1000 == 0 )
            printf( "deleted row %d\n", i+1 );
    }
    exit(0);
}


Now I let it run and run (started the insert ahead of the delete) and run and run (until i got 
bored).  After a couple hundred thousand inserts and a couple hundred thousand deletes -- I 
ctl-c'ed each one.


ops$tkyte@ORA9IR2> analyze index t_pk validate structure;
 
Index analyzed.
 
ops$tkyte@ORA9IR2> select del_lf_rows, lf_rows from index_stats;
 
DEL_LF_ROWS    LF_ROWS
----------- ----------
         15       2687
 

and it really really really depends on how you use the index and how the index is hit if a large 
DEL_LF_ROWS would affect your IO at all.

What if you 

a) remove old entries (low sequence numbers)
b) were always interested in new entries (high sequence numbers) 
c) so therefore you query:
   select /*+ first_rows */ * from t order by X desc;

and range scanned that way.  well, the high end of the index is going to be very packed -- and you 
never "page down" into the low end (you show the user the N newest entries and they page down and 
page down -- you probably never get to the "low end" of the index where the whitespace might be

2) yup, exactly.

3) If I were to observe over time that DEL_LF_ROWS was always *increasing* -- note "over time" 
"increasing" -- i would consider that a thing to take interest in.  

If "over time", it increased to say 50,000 and then stayed there, fluctuating up and down a couple 
of thousand even -- i would do nothing -- even if the number of leaf rows was 50,000 as well.  why 
?  well, obviously this index wants to be that fat, with that much white space and no matter how 
many times I put it on a diet...... it is going to get back to 50,000 deleted and 50,000 not




Just apply some thought to what you are doing day to day, think about "why", think about what you 
are trying to accomplish.  Have a metric or two to validate it.  It is always nice to be to show 
what really happens. 

4 stars Hopelessly stumped   September 16, 2004 - 8pm Central time zone
Reviewer: ARU from NZ
Hi Tom,
Great thread this. Never will I rebuild indexes needlessly.
BUT yesterday I got a call from a client who says batch jobs which were taking minutes are now 
taking hours and insists for a script with which he can check index fragmentation. He insists that 
no application changes have been made at all.
What else can be the reason behind the batche jobs suddenly taking so long.
Tom don't laugh but the database is Oracle7 and 200GB.
It uses rule based optimiser thus the clients emphasis on indexes.
Please do guide me as you do always,
Thanks heaps,
ARU. 


Followup   September 17, 2004 - 8am Central time zone:

this is going to be a "hindsight is 20/20" sort of thing.

In order to determine "whats different", we would need to know "what was normal".

Unless you have tkprofs that profile these batch jobs, that show what they used to do -- it'll be 
hard to know.

Ok, so how would you see this?  I rigged up an example:

drop table t;
create table t ( x int, mod_x int, y char(20) default 'x' );
drop sequence s;
create sequence s;
alter table t add constraint t_pk primary key(x,mod_x);


we are going to populate this table like this:


void process( int rows )
{
int  i;
                                                                                                
    EXEC SQL WHENEVER SQLERROR DO sqlerror_hard();
    for( i = 0; i < rows; i++ )
    {
        exec sql insert into t (x,mod_x) values 
                 ( s.nextval, mod(s.nextval,100) );
        exec sql commit;
        if ( i%1000 == 0 )
            printf( "inserted row %d\n", i+1 );
    }
    exit(0);
}



so, X will be an increasing sequence and mod_x will run 0..99, 0..99, 0..99 and so on.


The carefully crafted delete will be:

void logon()
{
EXEC SQL BEGIN DECLARE SECTION;
varchar   oracleid[31];
EXEC SQL END DECLARE SECTION;
                                                                                            
    strcpy( (char *)oracleid.arr, "/" );
    oracleid.len = strlen((char *)oracleid.arr);
                                                                                            
    EXEC SQL WHENEVER SQLERROR DO sqlerror_hard();
                                                                                            
    EXEC SQL CONNECT :oracleid;
    exec sql alter session set events '10046 trace name context forever, level 12';
}
                                                                                            
                                                                                            
void process( int rows )
{
int  i;
                                                                                            
    EXEC SQL WHENEVER SQLERROR DO sqlerror_hard();
    for( i = 1; i < rows; i++ )
    {
        exec sql
            delete from t where (x,mod_x) =
            (select x,mod_x
               from (select x, mod_x from t order by x, mod_x)
              where rownum = 1
                and mod_x <> 1 );
        exec sql commit;
        if ( i%1000 == 0 )
            printf( "deleted row %d\n", i+1 );
        if ( i%10000 == 0 )
        {
            exec sql commit work release;
            logon();
        }
    }
}


I did this in order to get a plan like this:

ops$tkyte@ORA9IR2> explain plan for
  2              delete from t where (x,mod_x) =
            (select x,mod_x
               from (select x, mod_x from t order by x, mod_x)
              where rownum = 1
                and mod_x <> 1 );
  3    4    5    6
Explained.
 
ops$tkyte@ORA9IR2> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------
 
--------------------------------------------------------------------
| Id  | Operation            |  Name       | Rows  | Bytes | Cost  |
--------------------------------------------------------------------
|   0 | DELETE STATEMENT     |             |       |       |       |
|   1 |  DELETE              | T           |       |       |       |
|*  2 |   INDEX UNIQUE SCAN  | T_PK        |       |       |       |
|*  3 |    COUNT STOPKEY     |             |       |       |       |
|   4 |     VIEW             |             |       |       |       |
|*  5 |      INDEX FULL SCAN | T_PK        |       |       |       |
--------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access(("T"."X","T"."MOD_X")= (SELECT
              "from$_subquery$_002"."X","from$_subquery$_002"."MOD_X" FROM
              (SELECT /*+ */ "T"."X" "X","T"."MOD_X" "MOD_X" FROM "T" "T" WHERE
 
 
              "T"."MOD_X"<>1) "from$_subquery$_002" WHERE ROWNUM=1))
   3 - filter(ROWNUM=1)
   5 - filter("T"."MOD_X"<>1)
 
Note: rule based optimization
 
23 rows selected.




so, this delete will read the index -- scanning to find the first X,MOD_X such that MOD_X is not 
1 -- and then delete it.  We are leaving behind in this index structure all of the x,mod_x's with 
mod_x = 1 (not a clean sweep as before).

Also, I'm logging out every 10k rows and logging back in and turning trace on again.

Here are the first 4 tkprofs:



delete  from t
where
 (x,mod_x)=(select x ,mod_x  from (select x ,mod_x  from t  order by x,mod_x )
   where (rownum=1 and mod_x<>1))
                                                                                                    
                                                 
                                                                                                    
                                                 
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute  10000      3.34       3.74          0     246225      40457       10000
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total    10001      3.34       3.74          0     246225      40457       10000
                                                                                                    
                                                 
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 158
                                                                                                    
                                                 
Rows     Row Source Operation
-------  ---------------------------------------------------
  10000  DELETE  (cr=20008 r=0 w=0 time=1411426 us)
  10000   INDEX UNIQUE SCAN OBJ#(30278) (cr=20000 r=0 w=0 time=69076 us)(object id 30278)
********************************************************************************
delete  from t
where
 (x,mod_x)=(select x ,mod_x  from (select x ,mod_x  from t  order by x,mod_x )
   where (rownum=1 and mod_x<>1))
                                                                                                    
                                                 
                                                                                                    
                                                 
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute  10000      4.71       5.19          0     681712      40479       10000
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total    10001      4.71       5.19          0     681712      40479       10000
                                                                                                    
                                                 
Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 158
                                                                                                    
                                                 
Rows     Row Source Operation
-------  ---------------------------------------------------
  10000  DELETE  (cr=20011 r=0 w=0 time=1443698 us)
  10000   INDEX UNIQUE SCAN OBJ#(30278) (cr=20000 r=0 w=0 time=126472 us)(object id 30278)
********************************************************************************
delete  from t
where
 (x,mod_x)=(select x ,mod_x  from (select x ,mod_x  from t  order by x,mod_x )
   where (rownum=1 and mod_x<>1))
                                                                                                    
                                                 
                                                                                                    
                                                 
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute  10000      6.36       6.38          0    1130588      40484       10000
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total    10001      6.36       6.38          0    1130588      40484       10000
                                                                                                    
                                                 
Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 158
                                                                                                    
                                                 
Rows     Row Source Operation
-------  ---------------------------------------------------
  10000  DELETE  (cr=20004 r=0 w=0 time=1460916 us)
  10000   INDEX UNIQUE SCAN OBJ#(30278) (cr=20000 r=0 w=0 time=91020 us)(object id 30278)
********************************************************************************
delete  from t
where
 (x,mod_x)=(select x ,mod_x  from (select x ,mod_x  from t  order by x,mod_x )
   where (rownum=1 and mod_x<>1))
                                                                                                    
                                                 
                                                                                                    
                                                 
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute  10000      7.54       8.39          0    1579542      40521       10000
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total    10001      7.54       8.39          0    1579542      40521       10000
                                                                                                    
                                                 
Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 158
                                                                                                    
                                                 
Rows     Row Source Operation
-------  ---------------------------------------------------
  10000  DELETE  (cr=20016 r=0 w=0 time=1530803 us)
  10000   INDEX UNIQUE SCAN OBJ#(30278) (cr=20000 r=0 w=0 time=117590 us)(object id 30278)



See the LIOs go up from 

  246k
  681k
1,130k
1,579k

and see the increasing CPU times.  Now I rebuilt the index and restarted the "batches":

delete  from t
where
 (x,mod_x)=(select x ,mod_x  from (select x ,mod_x  from t  order by x,mod_x )
   where (rownum=1 and mod_x<>1))
                                                                                             
                                                                                             
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute  10000      4.19       5.26         15     192185      40502       10000
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total    10001      4.19       5.27         15     192185      40502       10000


and it went back down, funny thing is -- the "classic method for finding fragmented (whatever 
that means) indexes", would totally miss this

ops$tkyte@ORA9IR2> analyze index t_pk validate structure;
Index analyzed.
 
ops$tkyte@ORA9IR2> select lf_rows, del_lf_rows from index_stats;
 
   LF_ROWS DEL_LF_ROWS
---------- -----------
      6505         194

not many del_lf_rows here eh?

So, ask yourself, do we have any degenerate cases like this -- a sweeping left to right index that 
leaves stragglers behind?


Now, to be fair, the other example above would show increased LIO's over time -- at a much much 
much much slower rate however (it took over 10 times the work to get the LIO's as high as we saw 
jump the first iteration here) -- but again, the "classic approach" (look for del_lf_rows) would 
have been meaningless!  utterly and totally.



So, look for slow by slow code that scans the left hand side, to find the first row to process, but 
leaves stragglers behind.   

5 stars Love all , Trust Few , Follow One   September 17, 2004 - 1am Central time zone
Reviewer: Nilanjan Ray from India
Great example and demonstrations as usual. Nothing could have been better.

Follow one -- That's You :). Others in the forum would agreee too.

Obviously by trusted list would include greats like: Carry Milsap, Steve Adams, Jonathan Lewis, 
Criag Shallahamer.  

Regards
Ray 


Followup   September 17, 2004 - 8am Central time zone:


I disagree, my scope of knowledge is actually quite limited in some respects.  I defer to others 
for many things.  I'm a developers DBA (if they are willing to listen), there are people who are 
much better at certain things....

follow your instincts.
follow that which you can prove.


It is like the difference between Astronomy, the science of the heavens, and Astrology, the art of 
pretending that if mars is properly aligned with jupiter your cache hit ratio will be superb today.

Follow Astronomers. 

5 stars Astronomy- Astrology-mars-jupiter-cache hit ratios   September 20, 2004 - 3am Central time zone
Reviewer: Nilanjan Ray from India
This is definitely Mr.*Modest* Kyte speaking.

"I'm a developers DBA..." People in the industry simply undermine the value/knowlege/capability of 
Development DBA unless you are someone like "Mr. Kyte"...True..and 100%factual. The server room dba 
(if I may call production dba-pls I am not generalizing) are looked upon with awe..Look I can 
change optimizer_* parameters...so and so parameters that can make make your application attain 
*escape velocity*. PL/SQL and SQL are just not their cup of tea. These simple things are 
developer's stuff. Then when one fine morning when one transaction/SQL simple refuses to run the 
dba would remotely loging....compute amazing mathamatical equations...tweak a few parameters. Even 
then after a couple of days the transaction/sql starts using even more temp segments. Then when 
this poor development dba takes the call, he is in no hurry-finishes his cup of coffee, does'nt 
need to tweak parameters..knows the database, system load, knows the access path, understands what 
went wrong from the tkprof output. Uses *a simple editor* to optimize the code, instruments it, 
load tests it and releases it. 

These are real life scenarios. People might agree, disagree.

And Mr. Kyte, I was not aware of this area of interest of yours "Astronomy- 
Astrology-mars-jupiter-cache hit ratios" ;). 

I would start looking at my cache hit ratios again when it falls below 99% "while mars is properly 
aligned with jupiter". Please provide me with a best practise link for this. :-D

Ray 


Followup   September 20, 2004 - 8am Central time zone:

It is true, I've seen many cases such that when mars and jupiter are well aligned, and solar flares 
are low (i'm pretty sure this is important, you know how solar flares can affect the computing 
speed of your cpu and the transfer rates of even solid state drives) -- end users report better 
response time.  Might be the placebo effect, but hey -- who cares.  Just align mars and jupiter and 
things are good.

Now, how do I get them to stop moving away, out of alignment, thats the tricky part.  Need more 
coffee to think about that one.  

5 stars one more time   September 22, 2004 - 11pm Central time zone
Reviewer: subbu from MN,USA
hey tom.. i see one more article
http://www.dba-oracle.com/art_dbazine_idx_rebuild.htm
you got to read that.. there are some proof also..
you know i've also seen cases where analyze of table was not improving anything and then analyze 
the indexes - no change.. what helped finally is dropping the stats, rebuilding indexes, analyze 
table. 
I'm sorry i dont have the proof for this right now as this happened long back. may be that index 
was requiring a rebuild which i might have come to know at the end of detailed analysis..
but at the same time -- incidents like this will always makes me to think why not to try rebuilding 
indexes when there is a problem. if the problem is not fixed then i can move to detailed analysis. 
ofcourse there is no harm in doing this right? 
Now i read what i typed and was wondering how i wrote like this even after reading the articles on 
"extended sql tuning". The reality is when there is a performance problem we are under lot of 
pressure to do something and make it perform better and we choose the easy hits if we know that it 
wont take much time.

The case which i quoted above where index rebuild helped, i wouldn't have done that if i know that 
index rebuilding is going to take more time. in which case i would have done detailed analysis 
before even thinking of rebuilding..

So can i say that if we have a problem which needs immediate fix then its ok to try index rebuild 
though it may or may not fix the time.

Do i sound confused? 


Followup   September 23, 2004 - 4pm Central time zone:

one time, after rebooting the system and flushing the network - -while looking outside, during a 
rainstorm, on a tuesday -- before 3pm (very very important, this doesn't apply after 3pm -- and 
remember, that is EAST COAST time, that is relevant) -- stuff went faster.


when your kid gets sick -- would you like your Dr. to say "well, this medicine worked really good 
on Sally and she had a 101 degree fever too sooooooo"

You should be able to look at the sql using that index (it is all there) and saying "you know, that 
LIO is really high".

have I told you about the guys who said "reorgs are always good, they never hurt..."  -- wow, can a 
reorg kill you if it has unanticipated side effects...

I'd rather have at least a clue before I tried anything -- at least a clue. 

5 stars experience?   September 24, 2004 - 4am Central time zone
Reviewer: A reader 
hi tom,
I am a great fan of YOURS and you always said experience is important than theoritcal learning.
is it not justifiable that we can take his (Don's) point 
as he has proven track record.

thanks 


Followup   September 24, 2004 - 11am Central time zone:

Experience is more relevant than "i know everything I know from books" -- proof: so many books are 
wrong in so many ways.


If you look at my book, my writings, I show when and where

o things apply (they help)
o things have no application (they do nothing but waste your time)
o things do not apply (they do more harm than good)

Because someone has been talking about Oracle for many years doesn't mean squat.  

And then you have the conundrum of  "A (who is expert) says 'x' is true", "B (who is expert) says 
'x' is false"


Now what?


I believe in numbers.
I believe in proofs.
I believe in showing.

I believe everything has a "good", "bad" and an "ugly"

So, tell me -- goto that page (the fallicies one) and show me one ACTIONABLE item -- a nugget of 
help, of truth -- that you can take home tonight and apply.

Besides the ones I pointed out he suggested which were:

o get more ram
o buy more cpu
o buy faster cpus
o upgrade your network
o trash your disk array
o heck, just get solid state



Give me something I can use -- all I see there is a bit of bashing "oh, those guys that say you 
should actually look for a root cause, gosh, I'm far too busy for that.  Just buy more hardware -- 
it'll fix it right up"

I'll stick with the cardboard on the thermostat thank you very much.  If you read the computerworld 
article -- the anlogy is awesome.  There you have people thinking "heat issue", but it is a 
configuration issue (cold air, blown on thermostat).  The fix -- buy another AC unit of course.  
The kicker -- it probably would have "apparently solved the problem" -- but not because they needed 
another AC, but because this AC's thermostat wouldn't have been placed right above a vent blowing 
cold air on it.  

It is wonderful to fix stuff by accident, ain't it.  Too bad the fix cost so much.


This isn't about experience.  You can have 20 years of "experience" in something and still not be 
"expert" (i'm not saying anything about anyone here -- i'm just saying "cause you been doing 
something for a long time doesn't mean you know how to do it best".  Look around you -- are there 
people you work with, that have been doing it longer, that you don't think "get it"?  I'll bet you 
there are.


Given two candidates in an interview, I'll tend towards experience -- but hey, I'm STILL GOING TO 
INTERVIEW them.  
 

5 stars Any Extraterrestrial Intelligence listening out there....   September 24, 2004 - 7am Central time zone
Reviewer: Nilanjan Ray from India
Hi Mr. Tom,

Just remembered that "when mars and jupiter were well 
aligned, and solar flares are low" we had UFO's landing on earth as well. But then when UFO's took 
off from earth mars and jupiter fell off once again and users started reporting poor response 
times. Mr. tom you should be glad that these people at, 
http://setiathome.ssl.berkeley.edu/,
are  trying to get ET's back on earth once again solve the mystries of mars-jupiter-cache hit 
ratios. 

Ray 


5 stars just bought his book   October 11, 2004 - 6am Central time zone
Reviewer: A reader 
hi tom 
i have just bought his book creating self tuning database and found it good, but just before that i 
bought ur book 
efefctive oracle by design.
ur book is like a holy book for me.
have u read his book. what are your reviews.
should i follow his book as we people depend the recommendations of  people like you. 


Followup   October 11, 2004 - 8am Central time zone:

I have an idea.

Use information that is factual.

Use information that can be proven.

Use information that not only comes with "do this" advice -- but also comes with "but watch out, it 
doesn't apply in this case" sort of information (eg: nothing is 100% true, nothing is 100% false -- 
things are not black and white).

Use information that the person giving you the information has convinced you with examples, test 
cases, *numbers* to be accurate.


Above all, use common sense :)

(i would not suggest using multiple block size tablespaces as a tuning device.  i would not suggest 
rebuilding all of your indexes with a 32k blocksize.  i would suggest benchmarking all advice that 
was not supplied with a benchmark heavily!!!!!) 

4 stars why ?   October 11, 2004 - 8am Central time zone
Reviewer: A reader 
(i would not suggest using multiple block size tablespaces as a tuning device.  
i would not suggest rebuilding all of your indexes with a 32k blocksize.  i 
would suggest benchmarking all advice that was not supplied with a benchmark 
heavily!!!!!) 

why ? any specific reason 

thanks 


Followup   October 11, 2004 - 8am Central time zone:

if you want to "fine tune the keeping/recycling" of objects -- you use the keep/recycle pools.

and most importantly -- because I haven't seen numerical proof of it "being better" (yes, i've seen 
the 'proof' that LIO's go down -- but, umm, that is sort of obvious, if the index block is 32k 
instead of 8k -- one might expect that).  I only see it as being harder to manage, more to think 
about.


so, someone (maybe that author?)  do a technical proof -- not "well, i've seen it be good I think". 
 It should be easy (or not).

But be sure to include "when this isn't good".  I can think of one -- a large table with an index 
that retrieves 1-100 or so rows at a time.  There, I can think of how the 32k blocksize on an index 
would very likely be detrimental to my performance.  I should only need 1, maybe 2 leaf blocks to 
perform that range scan with 8k.  I would need 1, maybe 2 leaf blocks with 32k.  However, I might 
have to do 4times the PIO to do it.  I might need 4times the buffer cache to hold it -- meaning I 
could definitely be INCREASING MY PIO needs with a 32k blocksize index.  My blocks bump out other 
blocks more often since we use 4x the buffer cache to hold these blocks.


I'd like to see the science that says "if you have this condition (cause things are not 
"universally applicable"), and you do these things -- then you might expect under this set of 
circumstances to experience 'this' ('this' needs to be the metrics we should be looking for, what 
numbers we are looking for)"

That's all -- pretend I'm from Missouri -- "show me"
 

5 stars Multiple blocksizes   October 11, 2004 - 10pm Central time zone
Reviewer: A reader 
"i would not suggest using multiple block size tablespaces as a tuning device.  i would not suggest 
rebuilding all of your indexes with a 32k blocksize"

I completely agree with everything you said and see your point. But, as a Oracle technology person, 
I see these new features, I see the reasoning behind them and where they might be useful. I would 
like to benchmark them in my system to see if they would indeed benefit my applications. How do I 
go about doing that?

Lets take the "recreate an index in a 32k blocksize tablespace" feature. What index stats, usage 
patterns, cardinality, etc, etc, should I look at to determine if a certain index would indeed 
benefit from being moved to a 32k blocksize tablespace?

Thanks 


Followup   October 12, 2004 - 7am Central time zone:

the reason for multi-block size tablespaces is, was and will be documented as "for support of 
transporting tablespaces from small block size oltp database to large blocksize data warehouses for 
ETL processing without the 'E'"

 

5 stars why ?   October 12, 2004 - 12am Central time zone
Reviewer: A reader 
great as always.

i have question for you. PLease tell me you answer these questions alone or you have a team, i a 
person like you also needs rest. i wonder someday i can also be like you.

thanks 


Followup   October 12, 2004 - 7am Central time zone:

unless the answer starts with "I asked <name> to answer and they say...." 

I answered it. 

4 stars review   October 12, 2004 - 4am Central time zone
Reviewer: A reader 
tom 
have you read this book Oracle SQL Tuning & CBO Internals by kimberly floss.
i was about to buy this book but since it has been co - written by don Burlesson, what are your 
views about this book. Please shed some light on it to make a decision.

thanks
 


Followup   October 12, 2004 - 8am Central time zone:

you'll have to make your own judgement calls as to whom you get advice from.

When I've read something and liked it, I'll point it out.  I haven't read this book, I am not 
qualified to comment on it one way or the other. 

2 stars about the book cbo internals ?   October 12, 2004 - 7am Central time zone
Reviewer: A reader 
about the book cbo internals ? 


1 stars ???   October 12, 2004 - 8am Central time zone
Reviewer: A reader 
What do you think about about this book, can you give me your opinion please.
It's called 'Annoy people by asking them to review books!'

Thanks 


5 stars Multi blocksize tablespaces   October 12, 2004 - 10am Central time zone
Reviewer: A reader 
You are dogding my question

"the reason for multi-block size tablespaces is, was and will be documented as "for support of 
transporting tablespaces from small block size oltp database to large blocksize data warehouses for 
ETL processing without the 'E'""

That just says that, say, 32k blocksize tablespace is likely to be used by customers in a "data 
warehouse", whatever that means nowadays! But you just advised that just because it is a data 
warehouse, one shouldnt jump to use 32k blocksize tablespaces. Thats why I was trying to get some 
scientific, methodical way from you by looking at stats, numbers, etc to determine if indeed I 
would benefit from 32k blocksize tablespace? 


Followup   October 12, 2004 - 10am Central time zone:

it means, 32k/16k is normal for DW.

it means, numbers smaller than that are normal for OLTP (all of the way down to 2k).


I DID NOT ADVISE ANY SUCH THING.  Please tell me where you saw that?  That I said "don't use 
32k/16k for DW"

I see "don't use mixed size blocks for tuning"
Where do you see "don't use 32k for anything" 

5 stars   October 12, 2004 - 10am Central time zone
Reviewer: A reader 
OK so you *are* saying that use 32k for a datawarehouse, always? Surely not. I understand what you 
mean, I am just trying to do my due diligence to determine if my datawarehouse would benefit from 
this new feature and requesting your help as to what steps I should follow to come to this 
determinination. Dont know how else to ask this. 


Followup   October 12, 2004 - 11am Central time zone:

I'm saying 

"in general, DW's use bigger blocks -- like 16 and yes, even 32k"

"in general, OLTP's use smaller blocks -- like 8 and yes, even 2k"


You pick -- but given that you picked say "16" for DW and say "8" for OLTP -- multiple block sizes 
are SUPPORTED so you can take a datafile from "8" and plug it into "16" so you can "ETL" without 
the "E" from your OLTP's to your DW's.


YOUR DW BENEFITS FROM THIS NEW FEATURE IF AND ONLY IF YOUR DW has a blocksize that is different 
from the databases you are transporting data from (tried to say that above, hope this clears it up 
-- multiple blocksizes are there to permit the transportation of a datafile from a database with 
blocksize X to a database with blocksize Y)

 

4 stars Domain Index   October 12, 2004 - 11am Central time zone
Reviewer: Kamal from INDIA
Hi Tom

Can you explain the use of Domain Index and where it can be used.

There is column called domixops which is showing failed even when the index is valid...what is the 
reason...

Thanks in advance..

Regards
kamal 


Followup   October 12, 2004 - 11am Central time zone:

Oracle text uses domain indexes... create index t_idx on t(text) indextype is ctxsys.context;

Oracle spatial/locator uses domain indexes....

they are "user defined" or "extensible" indexes -- you could create your own (but the ones we ship 
are usually enough"




DOMIXOPS is not a name familar to me.  Who owns it?  what is it on? 

5 stars   October 12, 2004 - 12pm Central time zone
Reviewer: A reader 
"in general, DW's use bigger blocks -- like 16 and yes, even 32k"

"YOUR DW BENEFITS FROM THIS NEW FEATURE IF AND ONLY IF YOUR DW has a blocksize that is different 
from the databases you are transporting data from"

We are still not on the same page. I am not talking about transporting tablespaces at all.

I am just trying to justify, rationlize, see if your first statements above is valid in my 
environment. In other words, I am trying to see if your "in general" would apply to my particular 
warehouse, thats all.  I am NOT asking about why multiple blocksize feature was invented.

Very simply, all I want to know is how do I go about determining if my warehouse would benefit from 
a 32k blocksize? You pointed out some caveats above "a large 
table with an index that retrieves 1-100 or so rows at a time ...". How do I go about *testing* and 
benchmarking 32k blocksize so as to arrive at a determination that it would/would not benefit me? 


Followup   October 12, 2004 - 1pm Central time zone:

you would have to test and benchmark your application, on your system.

If you look at our tpc-h's for example, we use 8k/16k blocksize.

it'll depend on so many factors -- such as "do you query rows always that are next to eachother?" 
-- if so, the blocksize won't impact the buffer cache efficiency so much being really large.  If 
the rows you query are far apart -- happening every say 64k of data (totally artificial here), you 
have to cache 32k for each row you are working with, i could cache the same amount of data in 1/2 
the cache with 16k and 1/4 the cache with 8k.


if your warehouse is built, stop, done.  don't rebuild it.

if you are building a warehouse, by all means -- test the typical operations you plan on 
experiencing and see if you can "measure" any difference (doubtful, not 100% ruled out -- but 
highly improbable).

8 and 16k are what the vast majority of the rest of the world is using (some people say "just use 
8k for everything").  

5 stars   October 12, 2004 - 2pm Central time zone
Reviewer: David Aldridge from Colorado Springs
For data warehouses you might find that the payoff for larger block sizes comes if you are using 
data segment compression, for which your rows ought to be physically ordered anyway. It might be 
worth benchmarking the compression ratio you can achieve on 16k and 32k blocks.

You might like to check metalink for any outstanding issues with 32kb blocks -- i recall that there 
was a bitmap index corruption problem a little while ago that forced us to migrate our entire DWh 
back to 16kb blocks. That hurt. 


Followup   October 12, 2004 - 2pm Central time zone:

well, all rows are physically ordered :)  randomly perhaps but physically ordered in some fashion.

The ordering that achieves maximum compression -- might be the ordering that puts the rows you tend 
to analyze as far apart as possible.


Consider:

SYM varchar2(4)
DT  date
VAL number

(stocks...) date is 7 bytes.  SYM is 5 bytes.  

The most "repetitive and big" field is DT.  If you order by DT, all of the information for ORCL is 
spread out over as many blocks as possible.  But, you query by ORCL for the last N weeks (or for 
SYM=xxxx in general, you analyze a stock)

So, your sort order for MAX compression is different than the order you would like the data in for 
analysis.


But yes, 32k will use less storage in a compressed and uncompressed form -- less block overhead 
(for uncompressed) and more opportunities to compress with a bigger block.


that last point was the reasoning behind saying "8 and 16k are what the vast majority of the rest 
of the world is using (some people say "just use 8k for everything").".   32k is not mainstream 
yet, as 16k was not too many years ago, as 8k was not before that.


 

5 stars   October 12, 2004 - 3pm Central time zone
Reviewer: David Aldridge from Colorado Springs
>> So, your sort order for MAX compression is different than the order you would like the data in 
for analysis.

Yes indeed, and given the choice I'd go for ordering by analytic requirements by default, but 
everything depends on how many blocks the average query would scan (assuming that the rows are 
physically ordered by analytic requirements). If the "average" query scans some hundreds of blocks 
then there's probably still room for further sorting to improve compression ratio. As you say, 
benchmarking is the thing.

>> that last point was the reasoning behind saying "8 and 16k are what the vast majority of the 
rest of the world is using (some people say "just use 8k for everything").".   32k is not 
mainstream yet, as 16k was not too many years ago, as 8k was not before that.

That's a relief -- I though I might get flamed for mentioning that :) 


4 stars Domain Index   October 14, 2004 - 4am Central time zone
Reviewer: Kamal from INDIA
Hi tom

Thanks for the answer.

I am sorry i have mentioned the column name wrongly in my previous Post.

the Column name is DOMIDX_OPSTATUS in DBA_INDEXES.

for a domain Index , the status is valid but this column DOMIDX_OPSTATUS is Failed.. what is the 
reason?

can you please explain with an example of how to create a domain index and use it in a query..or if 
not possible any reference links...

Thanks
kamal 


Followup   October 14, 2004 - 10am Central time zone:

my car won't start either....

one would need "more information" -- like "what you did", what the index is on, what TYPE of domain 
index (spatial, text, what) and so on...

search for

indextype

on this site -- indextype is ctxsys.context for example -- creates a TEXT index. 

4 stars Concerning the URL on index rebuilds mentioned above..   October 14, 2004 - 5am Central time zone
Reviewer: Hans Wijte from The Netherlands
I found this thread highly interesting to read, especially
the comments on the article mentioned in the URL
www.actoug.org.au/Downloads/oracle_index_internals.pdf

Well, I took a peek at this article, but it seems to me I
have read the wrong article because mr. F. declares the 
rebuilding of indexes to be largely a MYTH as well(see: the 
summary of his article); in fact if I'm not completely 
misstaken, this article states that almost everything you
point out as being myths, are also myths in his opinion.

Have I perhaps been reading a second ("updated") version ?

Best regards

Hans 


Followup   October 14, 2004 - 10am Central time zone:

i'm confused?  what did you mean?

???????? 

3 stars Explanation   October 15, 2004 - 4am Central time zone
Reviewer: Hans from The Netherlands
In the summary of his article he states the following:
1. The vast majority of indexes do not require rebuilding
2. Oracle B-tree indexes can become "unbalanced" and need to
   be rebuilt is a myth
3. deleted space in an index is "deadwood" and over time 
   requires it to be rebuilt is a myth
4. If an index has a height of "X" levels, it's inefficient
   and must be rebuilt is a myth
5. If an index has a poor CF, rebuilding it is a myth
6. To improve performance indexes must be rebuilt on a regu
   lar basis is a myth

To me all this doesn't sound like he's trying to make us
believe that indexes have to be rebuilt 


Followup   October 15, 2004 - 11am Central time zone:

1) i concurr
2) correct
3) correct
4) correct
5) correct
6) correct


i don't see anything wrong with that list.

the vast majority of indexes do not need to be rebuilt.

b*tree indexes cannot become unbalanced -- it is technically IMPOSSIBLE (so to rebuild because they 
are out of balance would be foolish, for they are NOT out of balance)

deleted space is not deadwood in general (my tests above show that actually).  Only in seriously 
degenerate, exceptional cases might there be an issue. (the myth is "deleted space is NEVER reused 
-- many many people believe that", it is NOT true at all, not even close to true)

the index height in general will not be affected by a rebuild.

rebuilding an index cannot in any way shape or form EVER affect the CF - the CF is a measure of the 
TABLE, not the index so much -- how sorted is the TABLE with regards to the index -- rebuilding the 
index will NEVER change how the index is sorted, hence it cannot affect the CF

Rebuilding all indexes on a recurring basis is a bad bad bad thing.  It is a myth.



So, where did either of us go wrong?  There are cases -- special, degenerate cases where a rebuild 
is helpful, even necessary.  But it is like 0.01% of the real world cases -- not 99.99%.


Still not understanding the disconnect here? 

5 stars Genesis of a Myth   October 15, 2004 - 3pm Central time zone
Reviewer: Alberto Dell'Era from Milan, Italy
> "deleted space is NEVER reused -- many many people believe that"

According to Dave Ensor ("Tales of the Oak Table", bottom of page 50), that used to be true for 
some prehistorical release of Oracle at least for (quoting)"completely empty leaf blocks". So, this 
a "once-was-true" kind of Myth.

Just noticed that while reading, perhaps someone may be interested. 

bye
Alberto 


Followup   October 15, 2004 - 5pm Central time zone:

all myths have foundations in long ago behaviour probably -- the explicit cursor myth for example 
(that you should open/fetch/close instead of select into) came probably from early forms (iag/iap) 
applications... 

5 stars Time-Resistant Myths   October 15, 2004 - 6pm Central time zone
Reviewer: Alberto Dell'Era from Milan, Italy
And what's the foundation of the Myth that says that you don't exist ?

Seriously - anyone I know, *without exception*, being him/her an Oracle professional or not, 
believes that asktom is run by a shadow team of ghost writers and that Tom Kyte is in permanent 
vacation at the Caribbeans, or perhaps a team acronym (Team for Operations and Maintenance ? Could 
be :) ...

Hard to find a test case against this, so i'm going to believe it myself ;) 


5 stars Hans, I think you're confused ?   October 15, 2004 - 6pm Central time zone
Reviewer: A reader 
Hans, it's the articles of Mr Burleson that Tom has been questioning, not Mr Foote. Tom uses Mr 
Foote's article as an example that dispels and proves many of these myths not to be correct.

You might want to re-read this thread.  


Followup   October 16, 2004 - 10am Central time zone:

Correct -- I really like the Richard Foote material, it is well done.  I encourage all to give it a 
read through and take it into consideration. 

5 stars   October 16, 2004 - 11am Central time zone
Reviewer: David Aldridge from Colorado Springs
In Richard Foote's excellent article he mentions a 9i 90-10 block split bug, that results in 
too-high a pct_free.

Is it fair to say that this is one situation where an occasional rebuild might be justified? Not 
for performance reasons I'd think, just if reducing the space allocation of the index was useful. 


Followup   October 16, 2004 - 1pm Central time zone:

it is a weird case that only affects a really badly written program.  i'd rather fix the code :)

but it is indexes on sequences that in general need watching (and the del_lf_rows ratio so commonly 
used won't work as shown above!).  when they sweep from the left to the right (like a queue -- put 
rows in, process them, delete them) but you leave a couple behind -- it can get bad over time.  A 
coalesce would fix them right up. 

5 stars My mistake   October 18, 2004 - 6am Central time zone
Reviewer: Hans Wijte from The Netherlands
Tom,

While reading your article i got the impression that you
were also questioning the article by Mr. Foote, but I
couldn't find anything wrong with ot. That's why I responded like that. I see the mistake was 
wholly on my 
side; I apologize for this confusion

Best regards

Hans  


5 stars Jonathan Lewis spot on   October 18, 2004 - 5pm Central time zone
Reviewer: A reader 
The two Jonathan Lewis links you highlight on your home page make the perfect postscript to this 
thread. Perhaps this Don Burleson dude will read it all and stop writing until he learns what he's 
writing about !! 


Followup   October 19, 2004 - 8am Central time zone:

Just for posterity (links on the home page come and go...) 

INCREDIBLY amusing, as well as full of useful information:  
Circular References proof by restatement  
http://asktom.oracle.com/pls/ask/z?p_url=http%3A%2F%2Fwww.jlcomp.demon.co.uk%2Fcircular.html&p_cat=C
IRCULAR&p_company=10
and  That was then, this is now . 
http://asktom.oracle.com/pls/ask/z?p_url=http%3A%2F%2Fwww.jlcomp.demon.co.uk%2FThat%20was%20then.htm
l&p_cat=THAT_WAS_THEN&p_company=10
Both of those articles are not only funny, but thorougly educational. Two thumbs up. 

5 stars Not likely   October 19, 2004 - 7pm Central time zone
Reviewer: Jeff from Atlanta
<Perhaps this Don Burleson dude will read it all and 
stop writing until he learns what he's writing about !!>

Hasn't stopped him so far. Try reading some of his responses to these things on the newsgroups. 

(You can get to them now at groups.google.com easily) 


4 stars Status N/A   October 20, 2004 - 5am Central time zone
Reviewer: Yogesh from Pune, India
Please confirm. 

If a index is locally partitioned, status of that index in dba_indexes is N/A

 


Followup   October 20, 2004 - 7am Central time zone:

in dba_indexes -- sure, cause there is no "index" to have a status of, there are many mini-indexes 
(in dba_ind_partitions) that have their individual status 

5 stars top oracle expert - myth?   October 20, 2004 - 9am Central time zone
Reviewer: A reader 
I'd like to understand how he became on of the world's top oracle db experts. Circular reference 
type of a thing again ...

"Donald K. Burleson is one of the world’s top Oracle Database experts with more than 20 years of 
full-time DBA experience. He specializes in creating database architectures for very large online 
databases and he has worked with some of the world’s most powerful and complex systems. A former 
Adjunct Professor, Don Burleson has written 15 books, published more than 100 articles in national 
magazines, serves as Editor-in-Chief of Oracle Internals and edits for Rampant TechPress. Don is a 
popular lecturer and teacher and is a frequent speaker at Oracle Openworld and other international 
database conferences. Don’s Web sites include DBA-Oracle, Remote-DBA, Oracle-training, remote 
support and remote DBA." 


4 stars Bitmap Indexes rebuild   October 21, 2004 - 5am Central time zone
Reviewer: Kiril from BG
Hi Tom
What about bitmap indexes on the tables with heavy inserts or updates of bitmap column.
I have tested this particular with 1 000 000 rows  with insert / update and commit at every 20000 
rows and there is unexpected growth in the bitmap index. 
After rebuild of index size is reduced.
Is it this 0.01 % where rebuild is reasonable?
Thanks 
Kiril 


Followup   October 21, 2004 - 7am Central time zone:

it is not unexpected -- in fact, it is entirely expected and predicable.

bitmaps are not relevant in a system with lots of row level modifications (they do not "survive" 
such operations).   

(i've written about this elsewhere on this site, jonathan lewis has an excellent series on this on 
dbazine.com)


this is a case where you set the index unusable, bulk load ALL rows and rebuild the index entirely. 

4 stars Unbalance?   October 21, 2004 - 7am Central time zone
Reviewer: A reader from USA
Tom,

Sorry for asking very naive question but have to.

What do they (or you) really mean the word "balance" w.r.t to index as? What is balance of an 
index?
 


Followup   October 21, 2004 - 7am Central time zone:

all leaf nodes are at exactly the same depth from the root -- eg: it always takes 3 IO's to get to 
the leaf (for example).

An unbalanced index would have it such that some leaf nodes could take 3, or 4, or 5 or 6 or N IO's 
to reach them.

in oracle -- the b*tree index is always balanced, always the same number of IO's to get to any leaf 
block in that index. 

4 stars Review of Tom's answers on rebuilding indexes   October 21, 2004 - 11am Central time zone
Reviewer: Cayton Janner from Austin, TX USA
This answer was quite helpful and Tom, I agree---you should never rebuild indexes except to move 
them or because you
have moved the underlying table and they have become "unusable".  I did rebuild some to get better 
balance
and eventually, they do go back to that "stable size"
you mentioned in your first response over 2 and a half years ago. 


Followup   October 21, 2004 - 2pm Central time zone:

(and you didn't "balance them" :)  

they are *always* perfectly balanced. 

5 stars btree index   November 1, 2004 - 2am Central time zone
Reviewer: A reader 
Hi

I am reading a Metalink note, 
http://metalink.oracle.com/metalink/plsql/ml2_documents.showDocument?p_database_id=NOT&p_id=30405.1
I wonder when will btree level increase? Undere what circumstances?

Also there is a paragraph which confuses me,

Inserting an index entry after index creation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
..........
Where an index key value has multiple entries, these entries are made into the  leaf block in ROWID 
order.  So all the blocks for the index key value are  scanned in turn until an entry is found with 
a greater ROWID than the new row,  and the row is inserted into that block (which may cause extra 
block splitting).   
The reason for this is for queries such as:         

SELECT some_columns FROM table WHERE COL_A  = valueA and COL_B = valueB;  

If COL_A and COL_B both have non-unique indexes, then because the entries in  each index are stored 
in ROWID order, it makes it easy to find the ROWID's that occur in both indexes.  Otherwise we 
would have to sort the ROWID's before we  could find the ROWID's that occur in both indexes.  

---------------------

I am confused, I understand that an index with multiple keys are composite indexes correct? From 
the text it seems that COL_A and COL_B are seperate single column indexes, how can single column 
indexes have multiple index keys...?

I dont understand why rowid is used, if say we have composite index ename, empno

1000, 10
1002, 20
1003, 10
1005, 30

how are these stored?

Cheers 


Followup   November 1, 2004 - 3am Central time zone:

the level will increase when a branch block level becomes "full" and we need another level.  

that paragraph was talking about using two indexes simultaneously.  an index join. 

5 stars   November 2, 2004 - 6am Central time zone
Reviewer: A reader 
Just noticed Mr Burleson is doing a presentation at Openworld on indexing, topic II d should be 
good for a laugh  ;-)

...
I Introduction

II Indexing Overview
a. Types of Indexes Available
Type
When to Use.
When it is not appropriate.
b. Indexing NULLs
c. The Need for Statistics
d. Rebuilding Indexes
Myth vs. Reality
Getting Stats for Free on Rebuilds
e. Testing Index Effectiveness 
... 


2 stars Oracle to blame ?   November 3, 2004 - 6am Central time zone
Reviewer: A reader 
After reading this thread, it appears obvious that Burleson understands little about indexes. Yet 
he writes articles, Oracle authorized books and presentations at Oracle Open World on the topic. No 
wonder us newbies get confused.

Shouldn't Oracle take some responsibility or am I missing something ? 


Followup   November 3, 2004 - 7am Central time zone:

"Oracle authorized books" -- no such thing "exists", Oracle does not "authorize" individuals to 
write books -- never has.

We cannot legally prevent someone from saying their mind.  It is not legal.  We cannot 
discriminate, we cannot blacklist.  If we said "we will prevent John Doe from presenting in Oracle 
forums" -- we would be open to litigation.

Oracle doesn't pick all of the presentations for OOW, they are selected by the user groups as well 
as I understand it.

The people must vote with their pocket books here.  

We can only be responsible for Oracle produced material.  


You or I could write a book (totally misleading book) about SQLServer if I wanted to -- no one can 
really stop us.  We are private individuals.

 

3 stars Poor Don!   November 8, 2004 - 7am Central time zone
Reviewer: Jensbob from Lower Saxony
> Just noticed Mr Burleson is doing a presentation at 
> Openworld on indexing, topic 
> II d should be good for a laugh  ;-)

He will feel like human lions food in the Rome colosseum.
 


3 stars oracle authorosed books   December 3, 2004 - 2am Central time zone
Reviewer: A reader 
the books are not oracle authorosed books but don has bokks published by ORACLE PRESS like 
statspack tuning
etc 


Followup   December 3, 2004 - 7am Central time zone:

so?  you too could probably publish a book under OraclePress.

It is a marketing relationship, pure and simply -- just like MS Press.  The books are not 
'sanctioned', they are not 'subject to approval' -- not anymore than anything by any publisher. 

3 stars   December 5, 2004 - 11pm Central time zone
Reviewer: A reader 
thats not fair enough ( maarketing relationship ) for readers if nobody is there to check its 
matter. i think 


Followup   December 6, 2004 - 11am Central time zone:

Oracle Press is a big company -- McGraw Hill.

They have a staff of editors.  These editors hire tech editors (like me -- I've tech edited for 
them).

These tech editors do "check its matter" as you say.  They have upwards of 5 or 6 people reading 
the book only for technical accuracy (eg: i don't correct grammar or flow, just find technical 
inaccuracies).

So, that said, McGraw Hill with a long history and reputation -- does tech edit the books.  But the 
tech editors themselves are human beings -- like me.  With varying levels of "experience".  

My point is "Oracle the company" doesn't tech edit these books.  There are tech editors from time 
to time that work for Oracle sure.

I believe when you buy a book -- you should look at the team that tech edited it to.  (look at the 
team I had on my books - the names there should instill a high degree of confidence that the 
material has been vetted by people who know).  I was as proud of the tech edit team on the book as 
I was of the content itself.  To the point where I have them point the bios in there so you can 
read about the people who did it.


In fact -- that may be as important as the author themself.  I've been in a situation where I've 
said to the publisher "if this material is printed -- I want my name removed from the book, I will 
not have my name associated with this content, people will believe I "believe" it to be true".  It 
is a powerful way to get stuff retracted.


 

3 stars   December 6, 2004 - 10pm Central time zone
Reviewer: jas from mumbai,india
we all like you because of your sincerity.

thanks
 


5 stars So do lions enjoy eating a turkey ?   December 9, 2004 - 4am Central time zone
Reviewer: A reader 
"He will feel like human lions food in the Rome colosseum.
"

Being unable to attend Open World this year, I would be interested in hearing feedback on Don 
Burleson's index presentation

Based on what I've read here and elsewhere, he doesn't seem to know a great deal. So has he changed 
his tune and learnt something of what he presents or were there a lot of lions with a bad case of 
indigestion in attendence? 


5 stars Lewis, Kyte, Burleson et al   December 10, 2004 - 10am Central time zone
Reviewer: A reader from US
I was planning to attend that Burleson session until I discovered who the presenter was!

Tom's and Jonathan's sessions were great as expected. BTW, many are still waiting for the hands on 
lap session that you promised, Tom!   :) 


Followup   December 10, 2004 - 11am Central time zone:

ha ha...  ;) 

3 stars   December 10, 2004 - 12pm Central time zone
Reviewer: David Aldridge from Colorado Springs
Don Burleson's presentation: 
https://www.openworld2004.com/published/1082/garmany_doc_1082.pdf


4 stars Hi,   December 10, 2004 - 1pm Central time zone
Reviewer: A reader 
I had a situation where the size of the index on two columns of a particular table was 1.5 gig and 
the size of the table with 6 columns was just 450MB.  
After rebuilding the index the size of the index came down to 240MB.

The table is however prone to all kinds of DML activities.

I don't understand why the index grow upto 1.5 Gig.  Can you please explain?  I am using oracle 
9.2.0.5.

Thanks,
 


Followup   December 10, 2004 - 7pm Central time zone:

it is called "white space"

You could have most likely "reclaimed" the space via a COALESCE as well.


Lets say you fill an index up with the numbers 1...1,000,000

You delete 75% of the rows (the numbers 1..25 STAY, 75..100 go, 101..125 STAY, and so on)

Your index will be as big as it was before
Your table will be as big as it was before.

Now, you insert rows 1,000,001 .. 1,750,000 (numbers 1,000,001 .. )

Your index is forced to put them on the "right hand side", the number 1,000,001 must go to the 
RIGHT of 1,000,000.  The index grows

but -- the table, the number 1,000,001 can certainly go where the row 990,990 *was* -- the table 
might not grow at all.


Things in an index have a "place"
Things in a (heap) table do not.


So, some "right handed indexes" like that can benefit from a coalesce from time to time, or maybe 
even a rebuild... 

4 stars So a 1.5 gig index on a several hundred meg table is ok?   December 12, 2004 - 12pm Central time zone
Reviewer: Mike Ault from Alpharetta, Ga
Tom,

I take it this is one of the special cases that represent only a fractional percent of cases? Yet I 
see these at almost all my clients. I also noticed in my reading of the Tales form the Oak Table 
book several of your reading list folks say "rebuilds of indexes" are beneficial.

I agree, they shouldn't be rebuilt on a whim, only when it is determined they have a problem. The 
ratio of deleted blocks to full blocks is a simple measure that can indicate this, is it a 100% 
indication? No. However it is a valid tool.

I also agree that the ultimate fix is to fix the code in many cases. Unfortunately over half the 
client sites I visit have 3rd party code they can't fix. In that case we have to treat the 
symptoms.

I would like to apologize to folks who read my articles about rebuild of indexes fixing cluster 
factors, I believe I recinded that advice where ever I could, however, I have little control over 
reposting. I do condone reordering of the index columns for a concatenated index to achieve better 
clustering factors and then apply that reorder to the appropriate SQL.

As to hardware fixes verses SQL fixes, it may be better money spent on older releases and 
third-party software to use the judicial application of specific technology to fix performance 
issues, especially if the only fix is to re-write a massive amount of SQL that could cost the 
company hundreds of thousands of dollars in lost time and productivity. Remember, many companies 
have bought into poorly designed software that they cannot easily discard. Again, in this case we 
have to treat the symptoms again.

I wish Oracle would take your practices to heart in all of its applications. I hate to take 
assignments on Oracle Apps sites because of the complex self joins, bad indexes, poor use of bind 
variables and cryptic use of undocumented parameters with no explanation or reasoning provided. 

I wonder also what would happen if you were to play devils advocate with your examples, instead of 
designing them to disprove, design them to prove some of these items and see what results you 
obtain. Sometimes what we see is what we look for.
 


Followup   December 12, 2004 - 7pm Central time zone:

I've never ever said "they are terrible, don't do them" (please, if anyone can find where I've said 
that -- point it out)

what I'm against -- a scheduled rebuild of every single silly index on the planet -- causing 
downtime, eating up resources and providing negative benefits in some cases.

I'm not saying "don't rebuild this thing" am I?

The ratio of deleted blocks to full blocks?  how do you do that? and what is a deleted block?  if 
you mean del_lf_entries -- that is useless (we clean out del_lf_entries on certain occasions -- 
every deleted but not reused slot is not a del-lf-entry!).  examples are above -- from the pro*c 
stuff that shows degenerate cases.


Not sure what to make of your last paragraph there.  The examples above clearly showed degenerate 
cases??!?  I carefully crafted them to show a breakdown -- and the type of processing that causes 
it.  I gave examples to show that space is reused efficiently.

did you read the entire posting?  (ctl-f for hindsight for example)

I do as many "postive" and "contra-positve" cases here.  Many (most actually I would say) are 
"postive" cases -- showing something to be true here.
 

4 stars Are you the Mike Ault that works for Don Burleson ?   December 13, 2004 - 6am Central time zone
Reviewer: A reader 
Because if you are, it explains your comments. 

Might I suggest you carefully read the excellent presentation by Richard Foot highlighted by Tom 
and learn why some indexes need rebuilding but why most don't.

Considering your guest appearence at the start of the presentation, it might do both you and Don 
Burleson some good.

Keep up the great work Tom and showing us how it really is.
 


3 stars To the last "A reader" ....   December 13, 2004 - 9am Central time zone
Reviewer: Gabe 
One can read/research both sides of the argument and draw his/her own conclusions ... one can 
express public opinions or statements (when backed up by proofs/facts).

Dishing out nominal advice <quote>Might I suggest you carefully read ...</quote> without leaving a 
name might be considered a bit patronizing.
 


Followup   December 13, 2004 - 10am Central time zone:

I encourage discussion on any and all topics myself. 

3 stars The last thing about Don Burleson.   December 25, 2004 - 8am Central time zone
Reviewer: Walter 
Don is a funny guy:

http://www.dba-oracle.com/redneck.htm
 


Followup   December 25, 2004 - 9am Central time zone:

and extremely sensitive 
http://dba-oracle.com/oracle_news/2004_12_22_webb.htm
 

4 stars   December 26, 2004 - 2pm Central time zone
Reviewer: Mike 
Tom, 
you have stated"
I'm not saying "don't rebuild this thing" am I?
"

Some times we do need to rebuild indexes, correct? If so, what are your criterions? Please 
illustrate them with examples as you have used to.
 


Followup   December 26, 2004 - 2pm Central time zone:

did you see the pro*c examples, they show you what I measure, actual, verifiable, measurable, large 
reduction in work performed -- against the type of index that typically benefits from this (a index 
you range scan, from the "left", where you leave over time one or two entries - deleting most of 
the others -- in other words, maybe a primary key on a batch table) 

5 stars   December 26, 2004 - 3pm Central time zone
Reviewer: dave 
the ireland article has been changed, he is a very unprofessional person 


5 stars temp tablespace for sorting   January 4, 2005 - 7pm Central time zone
Reviewer: reader 
(1) When Oracle rebuilds the index, if it needs more sort space, does it use temp or the index 
tablespace?
(2) When you create a NEW index, if it needs more sort space, does it use temp or the index 
tablespace?
Thanks. 


Followup   January 5, 2005 - 9am Central time zone:

1) temp, it sorts into temp and then writes into index.  however, you will see TEMP segments in 
INDEX, since when it is moving the data from TEMP into INDEX, it'll write them into TEMPORARY 
SEGMENTS (so that if the index create fails, SMON will just nicely clean up the temporary stuff 
that was being moved).

so, don't be confused when you see temporary extents in index, it just means we are writing the 
index to disk.  At the end of the write, we convert the temporary extents into permanent ones.


2) same as #1. 

3 stars good book   January 16, 2005 - 11pm Central time zone
Reviewer: A reader 
Oracle SQL Tuning & CBO Internals by kimberly floss is great book regarding CBO along with your 
expert one on one 
great reads. must buy.
 


4 stars Oracle Press   February 25, 2005 - 10am Central time zone
Reviewer: Richard from Oxfordshire, UK
I know you're not Mr. Oracle Press, but I have to say that for Oracle to allow any old hack to 
publish under their umbrella is both shocking and confusing to the customer, who would (not 
surprisingly) believe that the *Oracle* name would only be associated with quality.

I recently spent about $70 on an Oracle Press book (the author is somewhat famous for his 
idiosyncratic ideas about rebuilding indexes!), and, quite frankly, it's a right load of Eartha 
Kitt!

I bought the book because it was on a subject that is not widely covered (so I was limited to what 
I could pick from) AND because it was Oracle Press. I have other Oracle Press books which are fine, 
so it's been an eye-opener to have ended up with a stinker (and I do mean STINKER).

Come on Oracle, pull your finger out! Check-out the author and his/her work before lending them any 
semblance of respectability. I will probably not buy another Oracle Press book again (and feel free 
to contact me to arrange a refund!). 


3 stars Index Rebuild   March 14, 2005 - 1am Central time zone
Reviewer: APL 
How we can make text index rebuild faster? I am using  ctx_ddl.sync_index which is taking hours to 
finish. 


Followup   March 14, 2005 - 8am Central time zone:

look at the options -- parallel, up the memory settings and so on. 

3 stars tech books   March 15, 2005 - 11am Central time zone
Reviewer: A reader. 
Oracle Press books are of varying quality, as are those published by other groups.  Oracle provides 
tech reviewers (and sometimes authors) but the books are ultimately published by a division of 
McGraw-Hill.  In publishing parlance "Oracle Press" is an imprint.  The books published under the 
Oracle Press imprint have Oracle part numbers, and the standard label on the cover lists them as 
"official" and "authorized".  

Regardless of the publisher, all of the parties involved in publishing a book have an interest in 
providing the highest quality product possible.  If you have issues with a book's quality, take it 
up with the publishers so they'll do better next time.  They aren't trolling discussion boards for 
feedback; if you want your comments about an author or book to influence the future, tell the 
publisher.

 


Followup   March 15, 2005 - 11am Central time zone:

:1,$s/Oracle Press/All/g


I believe that you should judge a book not by it's cover but rather by:

a) I trust the author who wrote it

b) I feel comfortable with the review team, for the review team makes or breaks the book regardless 
of who wrote it.  I'm very proud of the people who have reviewed my books.  They would not be what 
they are without them.  I'm not sure that all technical books have even been through tech edits!  

c) the book was available in whole or part online for technical review (new way to judge -- most 
all books should be this way since about 2002/2003 I think)
 

5 stars   March 15, 2005 - 4pm Central time zone
Reviewer: A reader 
Couldn't agree more! 


5 stars Tom & Don   March 16, 2005 - 7am Central time zone
Reviewer: DBA from Manchester (United !), England.
Not a technical question - just interested in knowing whether you and Don get on well - or at all ? 
I presume he knows of your disdain for some of his theories. 


5 stars Don's Mystery about Rebuilding Indexes   March 22, 2005 - 12pm Central time zone
Reviewer: Jens from Germany
Now I got it, when I take a look at Don's Page and saw his consultant rates: Mr.SuperOracle wants 
$550 per hour! 

I bet, that if he would come to us, his first recommendation would be "Hey guys, first I would 
rebuild the indexes" - Ok than he sit very important in front of the terminal and waits for the end 
of the rebuild process. And after hours he earned a lot of money without nothing! GREAT JOB!

If Don take $550 per hour, Tom, what's your price? 10 Million $ for the same time? ;-)

http://www.dba-oracle.com/consulting_prices.htmurleson


4 stars Performance after Index Rebuild   April 1, 2005 - 8am Central time zone
Reviewer: Mahesh from Delhi India
Hi Tom

could you please let me know the way to measure the query speed improvements or any other 
improvement that result from Index Rebuilding.

I did this on my database and i released 2gb out of 3gb indexes space. 

Before Rebuild      After Rebuild      Space Recovered
  (Size MB)         (Size MB)         (Size MB)
---------------- ----------------    --------------
      3009              775               2234

Thanks
 


Followup   April 1, 2005 - 8am Central time zone:

do you have measurements (anything) from before the rebuild?  else it is going to be near 
impossible to measure any things

what metrics do you have from before? 

4 stars Index Rebuilding   April 4, 2005 - 9am Central time zone
Reviewer: Mahesh Kumar from Delhi India
Hi Tom

i have follwing information from INDEX_STATS table before and after rebuilding Indexes.  

SQL> desc  BEGIN_INDEX_STATS

 ------------------- ----------------------------
 OWNER                VARCHAR2(30)
 NAME                 VARCHAR2(30)
 HEIGHT               NUMBER
 BLOCKS               NUMBER
 LF_ROWS              NUMBER
 DEL_LF_ROWS          NUMBER
 DISTINCT_KEYS        NUMBER
 BLKS_GETS_PER_ACCESS NUMBER
 INDEXSIZE            NUMBER Calulated from dba_segments

SQL> desc  END_INDEX_STATS
 ------------------- ----------------------------
 OWNER                VARCHAR2(30)
 NAME                 VARCHAR2(30)
 HEIGHT               NUMBER
 BLOCKS               NUMBER
 LF_ROWS              NUMBER
 DEL_LF_ROWS          NUMBER
 DISTINCT_KEYS        NUMBER
 BLKS_GETS_PER_ACCESS NUMBER
 INDEXSIZE            NUMBER  Calulated from dba_segments


Is this information is sufficient ?

Let me know what other information is missing so i can collect before index rebuild.


Thanks
 


Followup   April 4, 2005 - 11am Central time zone:

You would like to also get the statistics for the queries making use of this index.

queries utilizing it to access data, did the consistent gets GO DOWN measurably?

modifications having to maintain the index, did their amount of work performed GO UP measurably.


and in a month, are you just back right where you began?  so you need "later_index_stats" as well.

 

5 stars index performance   April 5, 2005 - 10am Central time zone
Reviewer: PRS from USA
Hi Tom,
   I have an index in OLTP environment where it is a primary key and it's value is generated by 
oracle sequence. Index is analyzed and and it is on seperate LUNS on SAN than data. I have 500 
cocurrent users. When I see queries on that table using that primary key index, I see lot of 
contention and users wating to get the lookup on indexe. I have rebulded the index so many times 
but the problem still remains. Any ideas how do I reduce contention on this particular index?
Thanks,
PRS 


Followup   April 5, 2005 - 12pm Central time zone:

how are you measuring "contention", what does contention mean to you? 

5 stars index performance   April 5, 2005 - 1pm Central time zone
Reviewer: PRS from USA
user has to wait for that index lookup as so many people are looking at that table.
PRS 


Followup   April 5, 2005 - 6pm Central time zone:

tell me how you figured that out

show me some numbers, evidence.  how did you determine this to be true. 

3 stars coalesce and "right handed index" effect   May 4, 2005 - 3am Central time zone
Reviewer: A reader 
Hi

From one of your posts you mentioned that by coalsecing an index we can reclaim space. In your 
example you said this

"Lets say you fill an index up with the numbers 1...1,000,000
You delete 75% of the rows (the numbers 1..25 STAY, 75..100 go, 101..125 STAY, and so on)"

"Now, you insert rows 1,000,001 .. 1,750,000 (numbers 1,000,001 .. )
Your index is forced to put them on the "right hand side", the number 1,000,001 must go to the 
RIGHT of 1,000,000.  The index grows
"

Then you say

"So, some "right handed indexes" like that can benefit from a coalesce from time"

I dont understand how coalesce can reclaim space in this case since coalesce only merges "leaf 
blocks within same branch of tree". The new index entries will always go right hand side if the 
index is sequential, how can a coalesce help here? 


Followup   May 4, 2005 - 9am Central time zone:

it merges them and removes leaf blocks from under the branches, allowing those leaves to be put on 
the freelist (as they are empty now) to be used on the left hand side....

So, it lets leaf blocks from the left go over to the right. 

4 stars Great service to Oracle community   May 10, 2005 - 2am Central time zone
Reviewer: A Tom's fan for his dedication to Oracle community from Dallas
Tom: You are doing a great service to the Oracle community.  Any question on Oracle, we are all 
confident that "ASK TOM", he will answer you.  The discussion on Index rebuilding has cleared lot 
of myths.  I was also thinking that indexes do not re-use space.  I have a follow-up question on 
this topic. I have 200 tables in one of the DBs and all of them are Primary Keys or Unique Keys 
populated from Sequence by the application.  After Archiver is run, most of the old data is deleted 
from these tables.  Under these circumstances, do I need to do anything to maintain Indexes and 
their used space? 


Followup   May 10, 2005 - 8am Central time zone:

they may be the classic "sweeper" index that could benefit from a coalesce or rebuild. (see 
examples above) 

4 stars Index rebuilding   May 10, 2005 - 2am Central time zone
Reviewer: A Tom's fan for his dedication to Oracle community from Dallas 
By the way the oracle version I have is 817416 


4 stars Index rebuild/coalesce   May 10, 2005 - 9am Central time zone
Reviewer: Oracle DBA from Dallas
Tom: Thanks for quick response as always. Do you recommend coalesce over rebuilding index.  Does 
coalesce require downtime?  What is the best way of doing index coalesce?
2) I am forced to move a huge index from one TS to another at a client location.  Decision is not 
in my hands not to do. Do you recommend rebuilding the index or drop the original one and create 
the new one? Disk space is not a problem. 


Followup   May 10, 2005 - 10am Central time zone:

coalesce is an online operation (feature of enterprise edition).  see the alter index command 
(there is only one way to do it)

it works by taking adjacent leaves and putting them together if possible -- freeing leaf blocks to 
be placed on the freelist of the index.  It does not require 2x the space

an index rebuild can be done online (EE) and requires 2 times the space (or more or less, depends), 
it requires an exclusive lock on the index before and after the rebuild (so on a busy system, be 
very very careful) and will have overhead associated with it during the rebuild as it must remember 
what has changed in the table too.

2) that is a rebuild case for sure. 

5 stars rebuild index   May 11, 2005 - 8pm Central time zone
Reviewer: oracle dba from Dallas
Thanks Tom for detailed info.   


5 stars Index stagnation   May 18, 2005 - 12pm Central time zone
Reviewer: Christof Breker from Paderborn, Germany
In URL 
http://download-west.oracle.com/docs/cd/B10501_01/em.920/a96675/dba.htm#1009471
the OEM Event Test Reference Manual states:
When an indexed value is updated in the table, the old value is deleted from the index and the new 
value is inserted into a separate part of the index. The space released by the old value can never 
be used again. As indexed values are updated or deleted, the amount of unusable space within the 
index increases, a condition called index stagnation. Because a stagnated index contains a mixture 
of data and empty areas, scans of the index will be less efficient.

Would this be a situation when an index should be rebuilt as the manual suggests?

Regards,
C. Breker

 


Followup   May 18, 2005 - 12pm Central time zone:

I have filed a documentation bug as that statement could not be any further from reality.

Index space *is* reused, constantly.  That statement is totally false. 

3 stars Reason for regular rebuild?   May 24, 2005 - 3am Central time zone
Reviewer: Michael from Germany
Hi Tom!

We had the following issue - same query, same plan, same result, very different performance with 
index:

SQL> set autotrace on
SQL> set timing on
SQL> select count(*)
2 from yb_unit_sort_bin_result
3 where test_run_sk = 1100000;

COUNT(*)
----------
0

Abgelaufen: 00:00:00.05 <----- Fast, that is what i expected

Ausf³hrungsplan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=7 Card=1 Bytes=5)
1 0 SORT (AGGREGATE)
2 1 INDEX (RANGE SCAN) OF 'YUBR_YTRS_FK_I' (NON-UNIQUE) (Cost=31 Card=7247 Bytes=36235)

Statistiken
----------------------------------------------------------
0 recursive calls
0 db block gets
4 consistent gets
2 physical reads
0 redo size
188 bytes sent via SQL*Net to client
236 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
1 rows processed

Now, another query which is very slow, but it only in the filtering value for test_run_sk 
different.

SQL> select count(*)
2 from yb_unit_sort_bin_result
3 where test_run_sk = 800000;

COUNT(*)
----------
0

Abgelaufen: 00:06:21.08 <--- Very, very slow!

Ausf³hrungsplan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=7 Card=1 Bytes=5)
1 0 SORT (AGGREGATE)
2 1 INDEX (RANGE SCAN) OF 'YUBR_YTRS_FK_I' (NON-UNIQUE) (Cost=31 Card=7247 Bytes=36235)

Statistiken
----------------------------------------------------------
0 recursive calls
0 db block gets
135656 consistent gets   <--- Wow, that's a lot!
126204 physical reads
0 redo size
199 bytes sent via SQL*Net to client
238 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
1 rows processed

From this table an archiver process (SELECT-DELETE-like behavior) from the 3rd party application 
deleted many, many rows (about 25% of all rows). (I know that's not a good idea to "archive").

Support told us to rebuild this index (and other indexes on this table) at regular intervals 
because the archiver also runs at regular intervals.

Is this a case where a regular index rebuild is inevitable? 


Followup   May 24, 2005 - 7am Central time zone:

looks like a sweeper -- see the example above -- delete most but not all of the left hand side (old 
data) and you may well have lots of old values out there.

A coalesce may well solve the issue as well without necessitating a full rebuild.  Coalesce is a 
lower impact online operation than a rebuild online. 

5 stars Suggestion from Oracle, Advance Product Services group.   May 24, 2005 - 8am Central time zone
Reviewer: whizkid from APAC
We used to re-build indexes on a weekly basis and after learning from this site we stoppped doing 
that and moved to a specific problem solving approach. We recently had a database audit done by one 
consultant from APS, Oracle. During the audit, the topic of index rebuilding had come up and he was 
saying we should periodically rebuild index. When asked why, he said its because you need to re-use 
the free space when entries get deleted from the index. He's gone as far as putting it in his 
recommendations document... part of it is below...

Oracle Support Services
I
Recommendations
Database maintenance strategy
Currently the peformance of the database is looking good, but few
modification or changes to the database will give a better/optimal
performance. The suggestions/reccommendations are given on that basis
only.
Index Rebuild
Observation
Currently indexes rebuilding was carried out as an adhoc process.
Recommendation
Indexes should be rebuilt periodically. The following query can be used to
check the need of index rebuilding.
Select height, del_lf_rows/lf_rows from index_stats;

This query should be run immediately after one particular index is
analyzed. Any index which has del_lf_rows/lf_rows>0.2 or height >3
should be considered for rebuilding.

------

If support from Oracle itself spread such myths, then customers will believe them. Shouldn't 
something be done about it??? And we pay substantial amount for the product support. What do you 
suggest? 

P.S. I have their audit report with me in which this is mentioned. I can send it to you if you want 
to have a look at it yourself.. 


Followup   May 24, 2005 - 9am Central time zone:

we can only defeat the myths one person at a time.  When I see it in the documentation, I get it 
fixed.  When I see it in writing, I point it out.  

 

4 stars Myths   May 25, 2005 - 4am Central time zone
Reviewer: Michael from Germany
You can find this recommandation in MetaLink, too:

http://metalink.oracle.com/metalink/plsql/ml2_documents.showDocument?p_database_id=NOT&p_id=108573.1
states:

"Then check INDEX_STATS view particularly columns LF_ROWS
and DEL_LF_ROWS which shows current number of entry slots in 
leaf blocks. On the other hand LF_ROWS_LEN and DEL_LF_ROWS_LEN shows
the total number of  bytes associated with these entries.

As a rule of thumb, when the number of or spaced used by 
deleted entries is greater than 15 - 20% of the total entries 
you should consider rebuilding the index." 


Followup   May 25, 2005 - 7am Central time zone:

well, you know what Rule of thumb is abbreviated as ;)

It really depends on the type of data you are indexing.  If this index is on a field that is 
regularly updated -- I wouldn't be worrying.  As you update "A" to "M", you'll get a deleted leaf 
row in the "A" section of the index and either create a new leaf row OR reuse an existing deleted 
leaf row in the "M"'s.  As the index entries move around -- you might at any point in time have 40% 
of the index "deleted leaf rows" -- but that is OK (many indexes run at 40% 'empty')

And the advice won't find many indexes that are in need of it -- the sweeper above for example 
won't have a high deleted leaf rows, it would never find it.  But it would be a candidate. 

5 stars documentation bug?   May 25, 2005 - 11am Central time zone
Reviewer: SDiZ from Hong Kong
Is that possible to file a documentation bug on this?
We shouldn't let a myth like this spread ....

I can understand why people rebuild index when they experience performance problem... But 
recommanding people rebuild index even if they don't have any problem is really evil...

 


Followup   May 25, 2005 - 2pm Central time zone:

the email has already been sent, the wheels are in motion. 

5 stars Meaning of "balance"   June 9, 2005 - 7pm Central time zone
Reviewer: Brandon Allen from Phoenix, AZ
I've been reading a lot on this subject of index balance lately - read all of Richard Foote's 
excellent paper and much of the others and it's occurred to me that much of this argument may be 
due to the ambiguity of the word "balance".  

Tom and many others describe balance as the number of levels between the root and the leaves, which 
is of course always consistent throughout the index so, by this meaning, an index is most certainly 
always balanced.

However, if you define balance as the density throughout the leaf blocks, then by this definition 
an index can certainly become unbalanced.  Tom gives a good example of the "sweeper" with the 
monotonically increasing values on the right side and sparse values remaining on the left.  Imagine 
the dense, pct_used=90 blocks on the right side of a scale and then the sparse, pct_used=5 blocks 
on the left side and you have an index that is indeed out of balance.
 


Followup   June 9, 2005 - 10pm Central time zone:

I agree with your premise but:

Well, "balance" in the context of a B*Tree index is not ambigous.

But, if by "out of balance", someone means "this phenomena", with no further explaination....


if you google 
"out of balance" oracle index

the first hit is:
http://www.devx.com/gethelpon/10MinuteSolution/16596
but there are SOOO many things wrong in that article, it is hard to know where even to begin or 
what the author meant by "out of balance"

the second is:
http://dba-oracle.com/oracle_news/2004_9_20a_jenkins.htm
but that is a circular reference in a way.

but I suppose it goes back to "saying something in an understandable way".  Out of balance is not 
ambigous (in the context of a b*tree which is definitely self balancing)

It is not "tom and many others", it is in fact the definition of the structure itself.

This sweeper is one of the very very few cases where a B*tree index benefits from a coalesce or 
rebuild -- but even then you must

a) hypothesize that this index needs be rebuilt (say WHY you are going to do it)
b) measure somethings (take metrics) so see what the index does today (v$sql, executions -- other 
views to get the IO's performed while scanning this index)
c) rebuild
d) re-measure to see if you achieved your goal and to measure how often you might need to do this.

It takes like 10 minutes extra.  And it is worth it.


And remember, it depends on how you use the index.  Take that 5 and 90.  If you do keyed reads -- 
guess what?  It doesn't matter.

If you do "find me the minimum value" -- it may or may not matter.

If you do "start with this key and get the next 5 rows" -- it probably doesn't matter.

It is only if it matters... that we care. 

4 stars 108573.1   June 10, 2005 - 3pm Central time zone
Reviewer: Tamil from ATLANTA
Hmmm,
Tried to access 108573.1 doc. 
And what I got is:

MetaLink V2 - Error Message 
 Note entry 108573.1.cannot be displayed. Possible reasons are:
1. The article is not classified as publicly accessible ("non-public")
2. The article's content is being updated and it is temporarily unavailable but will be made 
available again soon.
3. The article has been deleted from this serve r.
4. The article number does not exist (it was referenced incorrectly).
5. If you still have questions about why you couldn't access this article, please use the Feedback 
button at the bottom of the left-hand menu bar.  
--------------------------------------------------------------------------------
 
!!! out of balance ?

Tamil 


Followup   June 10, 2005 - 3pm Central time zone:

I had them remove that article due to it's being "quite technically not correct"

As I hit misinformation -- I either get it corrected, or I try to get the author to correct it, or 
failing that -- you might see me comment on it here.

I do it for everyone, not to individuals, not to single organizations.  Anyone with "bad 
information" gets a chance to correct it, retract it, or failing that -- have it commented on.

And I hope others do the same for me, I type too fast some days as well -- when you see something 
questionable or just plain wrong -- call me on it, please. 

5 stars Meaning of "balance"   June 10, 2005 - 6pm Central time zone
Reviewer: Brandon Allen from Phoenix, AZ
Agreed Tom.  I wasn't disputing any of the points you have made - I was just noting the observation 
that much of the confusion may be due to a misunderstanding of the meaning of "balance" as applied 
to B-Trees.  In general both meanings are valid, but technically the one you use is the standard 
meaning as defined by Oracle so it is obviously the correct one.  Interestingly, I just found this 
article from Jonathan Lewis making my exact same point a few months ago: 
http://www.dbazine.com/oracle/or-articles/jlewis13
Under the subtitle "Why is the Myth so Strong", he states: "Remember that the definition of the 
word "balanced" has a very strict meaning when we are discussing B-trees. There is, however, a 
completely different interpretation that could be used for this word." and then continues to 
present the same idea I had.

Thanks for your time! 


Followup   June 10, 2005 - 6pm Central time zone:

I totally agree, that is why sloppy writing, hyperbole, grandiose statements, things that the 
national enquirer could have written....

will draw my attention immediately.

You want to talk technical?  Be precise, don't make up new meanings.  Don't make people guess what 
you MIGHT have meant, maybe.

And if you talk in generalizations, forget it, game over player one, you lose ;)   

4 stars So misguided and thankx for all the info   June 27, 2005 - 8am Central time zone
Reviewer: Eswar 
Hi Tom,

I was about to rebuild my indexes [yes misguided by dbzine doc] in my test mechine. But i 
accidently found this. Now, i wont, better i will do an analysis of the indexes and then think abt 
it.

Thanks again..

 


5 stars Skeleton in Tom's closet :-)   June 28, 2005 - 6pm Central time zone
Reviewer: Brandon Allen from Phoenix, AZ
Tom, I just found a response from you on a Metalink forum note from back in 2002 (DocID 
258194.995), in which you refer the user to Metalink Note 77574.1 (among others), which in turn 
includes the following statement: "The more deleted entries exist on an index, the more unbalanced 
the index becomes."  This statement is followed with advice to rebuild the index if 
del_lf_rows/lf_rows > 20%.

Thought you might want to get that Metalink note corrected :-)

Also, the same note also says "Leaving indexes with high PCT_DELETED [del_lf_rows/lf_rows] without 
rebuild might cause excessive redo allocation on some systems."

This doesn't make any sense to me - can you confirm and explain if there is any truth to it?

Thanks,
Brandon 


Followup   June 28, 2005 - 8pm Central time zone:

but I've *never* posted on metalink?

can you clarify? I pulled up that posting, I see a David Brinkman, a certain Mr. Burleson, and a 
Tom Villane.

where exactly do you see me referenced? 

5 stars Tom vs Tom ?   June 29, 2005 - 2am Central time zone
Reviewer: A reader 
Brandon,

Seems a bit unfair to attribute comments to Tom Kyte when they were actually made by a different 
Tom, Tom Villane. I hope you don’t criticise Tom Kyte’s acting abilities simply because you didn’t 
enjoy 'War of the Worlds' :)
 


5 stars Tom vs Tom   June 29, 2005 - 6am Central time zone
Reviewer: Mancman from UK
I though it was Tom Cruise in WofW ? 


Followup   June 29, 2005 - 9am Central time zone:

It is, the poster above you was pointing out that just because someones first name is Tom, it 
doesn't mean it was me :)

On the referred to metalink thread, there was a Tom participating, but it was not me. 

5 stars   June 29, 2005 - 9am Central time zone
Reviewer: dave 
is note 77574.1 valid at all? 


Followup   June 29, 2005 - 9am Central time zone:

it is mostly benign.  

with the 9i caveat - you can ignore the blevel.  Although think about it.  say you rebuild all 
height 4 indexes and you end up with.....

height 4 indexes.  do you rebuild immediately?  That advice is dodgy -- very circular.  

I'll just keep saying it:

if you are going to rebuild
  have a reason a goal for doing so
    so you can collect some metrics, makes measurements
        so you can verify you've achieved a stated goal
           and can monitor this over time, to help determine if in fact you need
           to keep doing this.


There are the sweeper indexes.  They can benefit from a periodic rebuild (each has their own period 
however).  But those, those you should "know" - they are monotomic (left or right hand side) and 
get 'purged' but not completely purged in general.

You should *know* without even looking what indexes those are!

Many of my applications tend to not delete or to use partitioning to facilitate purging.  I don't 
have sweepers by design. 

5 stars I'm a big dummy   June 29, 2005 - 7pm Central time zone
Reviewer: Brandon Allen from Phoenix, AZ
Sorry about that - I must've read too fast and mixed up my Toms.  I should've known better than to 
think Tom Kyte would've recommended that article.

My apologies,
Brandon 


4 stars ORA-08102   July 6, 2005 - 6am Central time zone
Reviewer: a reader from kuwait
Dear tom , what can i do with this error ORA-08102 ?? 
i try read alot but reach nothing .!
 


Followup   July 6, 2005 - 8am Central time zone:

contact support. 

3 stars Index Rebuild   July 12, 2005 - 4pm Central time zone
Reviewer: Rob H from Winnipeg MB
I am currently at a new position as a DBA and of course, there are several DBA's here with their 
rules as to how to manage databases.  I am having issues with many of their rules (like the fact 
most of their databases are 9i and they extent tablespaces manually...).  However, in a discussion 
I was made to feel like quite a newbie due to my stance against index rebuilding.  They claim that 
index rebuilds can(and have) recovered several gigs of index tablespace.  That is proof enough that 
periodic rebuilds can continue to maintain low index space usage (this is confusing to me and using 
your diet analogy its like starving the patient).  I have been reading a lot on this and the one 
fact that I'm confused with is this line:

"Index space *is* reused, constantly.  That statement is totally false."

Is this in the Oracle Documentation somewhere?  I have looked in the Concepts and DBA Guide and I 
cannot find any comment stating that space is re-used.  The best I could find was "All blocks of 
the B-tree are three-quarters full on the average." and "Inserts, updates, and deletes are 
efficient, maintaining key order for fast retrieval."

Their claim is that when rows are inserted into the table, the space is added to the index. I 
agree.  You remove those rows from the table and the table 'potentially' could free up the space 
for new rows, but that the index will remain at it size. Continual addition and deletion to a table 
will "ever-increase" the index.  Thus manditory rebuild is nessecary to reclaim wasted space (is 
this what you refer to as white space?).  I had agreed with this until I saw your post stating 
index space is reused. 

Thier rules for rebuild are:
1. report if index levels > 5
2. report if deleted leaf rows/total leaf rows > .10

Their entire argument is around the fact that space is recovered.  They have proof.  I am trying 
hard to understand all aspects.  You agree that there can be times when a coalesce is beneficial(an 
example is large deletes, followed by large inserts and repeat, this is an example of a transaction 
system keeping x records online, then archiving them to datawarehouse).

Any clarity on that statement. 


Followup   July 13, 2005 - 10am Central time zone:

... They claim that 
index rebuilds can(and have) recovered several gigs of index tablespace. 
...

for how many days, permanently?  and how much work was the system doing in the days following the 
rebuild as these indexes set about getting fat again.....


Stating that index space is reused would be stating the "obvious".  Do you have references where it 
says "we don't reuse it".


and if they rebuild an index with height >5 and it turns into a rebuilt index with height >5 what 
do they do then?

and the deleted leaf rows is funny, that one doesn't catch the type of index that might need a 
rebuild -- a sweeper index :)  Look for classic method for finding 
fragmented (whatever that means) indexes" on this page.


They have proof that space is recovered, for a couple of minutes, and then -- what happens??

tell them to do this, measure the index growth daily after their next rebuild and see if some of 
the indexes don't just "peak out" and stop "growing" (they attain their weight, their degree of 
breadth, and stay there).  And then do it again next month.

Ask they "well, we don't seem to permanently reclaim squat and these indexes just grow back to what 
they were and THAT my friends takes work, to have an index grow" 

5 stars Avoid that TOP 'Expert'   July 25, 2005 - 6am Central time zone
Reviewer: Bill from Brussels, Belgium
Amused at the comments much further up the thread regarding one of the "world’s top Oracle Database 
experts".

That said: Tom is not exactly shy and unforthcoming when he puts himself "among the most 
knowledgeable Oracle professionals in the world". Still I guess it's all in pursuit of maxing the 
sales of his book.

Tom is indeed extremely knowledgeable and I have learnt so much from reading his stuff, but 
sometimes I have to think is this guy real. In the section on LMTs in his book : "I'm not kept 
awake at night wondering if a PCTINCREASE is going crazy on me or if my tablespace will be 
fragmented like a Swiss cheese".

I mean for heaven's sake. There are thousands starving to death in Niger and bombs going off in 
London and Egypt. However, since the advents of LMTs, Tom at least now gets a peaceful night's 
slumber, not fretting about his PCTINCREASEs. Come on!

I do enjoy much of the Oak Table's stuff and they really are among the finest sources of Oracle 
info. But sometimes they do come across as a mutual backslapping, ego-stroking society. Hey guys 
aren't we good?

What I want to know is how comes there are apparently no female members bringing a bottle of whisky 
to the Oak Table. And considering the amount of whisky being drunk and baarfing going on, no wonder 
‘Brushco’ nearly went down the toilet so to speak :-)
 


Followup   July 25, 2005 - 8am Central time zone:

so, mundane work related tasks never bother your sleep at night?  Until August 11th, I can assure 
you I'll probably wake up at least once or twice and worry if I'm not making my deadline for volume 
II of the book.

And, since LMT's came out -- I'm not worrying about about pctincrease, how about you? 

I didn't get that last comment about the ego-stroking thing, seriously.  Where do you see that?  
for me, it is an email list, a place to ask questions and discuss.  Outside of that - what sort of 
backslapping presence does it have?

and there are female members. (no idea what brushco is...) 

4 stars The band of merry men.   July 25, 2005 - 11am Central time zone
Reviewer: A reader 
Thank you kindly for your reply and good luck with the second volume. I look forward to reading it 
when it becomes available.

I can't say I really ever wake up in a cold sweat and palpitations fretting about some object 
setting in a database. Sometimes I wake up in the middle of the night with what I think is a 
solution to a problem, but worrying? No. I believe in doing my work as conscientiously as I can and 
if a problem does arise solving it in a calm and methodical manner. But worrying over an Oracle 
database? I really don't what that achieves. And relative to all this terrible stuff going on in 
the world at the moment, my day to day DBA problems are totally insignificant.

Brushco is the 'mythical' company in 'Tales of the Oak Table' that Mogens Nørgaard and his merry 
men save from calamity, while it seems drinking copious amounts of whisky and patting each other on 
the back gathered round the Oak Table at his home in Denmark.

It seems to be all boys quaffing back the hard stuff while  Mogens' missus appears to do nothing 
but run around after them all the time! 


5 stars self proclaimed guru.   August 3, 2005 - 10am Central time zone
Reviewer: Sandy from London, UK
After reading through this thread, I have realised that
I've been really unlucky to have bought 2 books written by a self proclaimed Oracle guru whose 
second name starts 
with a 'B'... I never understood the books... one was about STATSPACK and is the worst technical 
book I've ever read! The first thing I plan to do when I get back home is 
to dump those books in a skip.. or maybe first use a shredder, lest some unlucky bin-man finds 
them!
Sorry to rant on this thread - just trying to calm down :-)) 


4 stars Clustering factor is very high for the table.   August 23, 2005 - 2am Central time zone
Reviewer: Neeraj Ranjan Rath ,Hyderabad from India
Hi Tom,
I am working in wel known Telecom Billing system.
For a particular table i found the following details as  clustering factor.
    BLOCKS CLUSTERING_FACTOR
---------- -----------------
    196205           6884676
    196205            747475
    196205            959798
    196205           1756130
    196205           1277388
    196205            115067
    196205           1575241
The clustering factor seems to be very high.The query which is using the the particular table is 
using index scan.
Do we need to reduce this clustering factor?
If yes please let me know how i can do that.
I have analyzed the table for all indices.But the clustering facter seems to be increasing.
Please advise me ! 


Followup   August 24, 2005 - 3am Central time zone:

do you have access to Expert one on one Oracle?

You need to understand what a clustering factor is (a measure of how sorted the table is with 
regards to the index keys).

You have to understand that a table can be "sorted" one way on disk (so in general, a single index 
will typically have a chance at a good clustering factor and the rest -- well, won't).


Are you doing a LARGE very LARGE index range scan using a single one of these indexes frequently? 

4 stars how to show that, my indexe rebulding is going on?   January 9, 2006 - 4pm Central time zone
Reviewer: Matte from Austin,Tx
Hi, Tom 
This is something different for an DBA.
Here is an simple procedure to rebuild the indexes. 
In my environment I send this script to the end users to rebuild their indexes themself. My 
environment is just like an distributed database system where the databases are located in the 
client locations .Because of the time taken to rebuild the indexes the end user sometimes 
confusing, whether system hanged or is it still rebuilding indexes. 

My requirment is :
I would like to print some "."  while rebuiling indexes
For example, If an index takes 3 minutes to rebuild, I would like to display 6 dots at the prompt( 
one dot per 30 secs) while the rebuilding is taking place. So that end user does not confuses 
whether it just hanged or continuing.

I am not getting any idea to print the dots and rebuilding the indexes parallelly.

Hope you understood my idea!!!!
Thank you in advance.
######################################################
create or replace PROCEDURE rebuild_all_indexes
AS
V_INDX_NAME user_indexes.index_name%type;
cursor index_cur is select index_name from user_indexes where index_type='NORMAL';
BEGIN    
    OPEN INDEX_CUR;
    FETCH index_cur INTO v_indx_name;
    LOOP
            EXIT WHEN index_cur%NOTFOUND;   
        dbms_output.put_line('Rebuiliding index for '||v_indx_name);  
            Execute immediate 'ALTER INDEX '||v_indx_name||' REBUILD ONLINE COMPUTE STATISTICS';    
      
        dbms_output.put_line('Completed rebuiliding index for '||v_indx_name);  
        FETCH index_cur INTO v_indx_name;
    END LOOP;
    CLOSE index_cur;
dbms_output.put_line('Rebuiling of INDEXES is completed');
END;
######################################################### 


Followup   January 9, 2006 - 6pm Central time zone:

why are you rebuilding them in the first place.

I can fix this problem immediately - just make the first line of code look like this:

...
begin
   RETURN;  <<<=== new code
   open index_cur;
   ....

 

5 stars   January 9, 2006 - 11pm Central time zone
Reviewer: A reader 
Great response, as usual. 


5 stars Thanks for the reader!!!   January 10, 2006 - 1am Central time zone
Reviewer: Matte from austin,TX
Thanks for the answer (professional) Tom,

Here is some thing i would like to tell you(espacially for the reader who commented for the 
answer).

>All environments will not be same.

>End user expectations will change everyday and it is our responsibility to provide the best 
interactive service to my clients.

>It does not make sense to comment on every answer (?professional?)

 


5 stars Rob   April 18, 2006 - 10pm Central time zone
Reviewer: A reader 
Tom,
I have a sql that does a AND_EQUAL join of 2 indexes..Is there a way(like a hint) to force that not 
to happen? I just want to use one index??
Thanks 


Followup   April 19, 2006 - 8am Central time zone:

begs the question "why"


but sure, if you apply some sort of "dummy function" to the indexed column - that would typically 
preclude the use of an index on that column. 

5 stars   April 19, 2006 - 9am Central time zone
Reviewer: A reader 
the reason is just using one index the query runs faster..but when the and_equal happens it runs a 
lot slower..the 
table also has STATS gathered..but still goes for a AND_EQUAL whch puzzles me...Can you please 
validate the below article..
http://people.aapt.net.au/roxsco/tuning/and%20equal.html
Thanks
Rob 


Followup   April 19, 2006 - 10am Central time zone:

show us the autotrace traceonly explains and the tkprofs here. 

3 stars Summary   April 19, 2006 - 3pm Central time zone
Reviewer: Daniel 
Just try to summarize all the comment, and see if i have understand it correcly:
----------------------------------------
Your arguement:
  1) Rebuilding index may make SELECT queries faster, but usually it won't last long. 

  2) The structure of the B*Tree will get to an equbilium point anyway, if your access pattern does 
not change.

  3) INSERT/UPDATEs are going to be more costy during the above process.

  4) Usually, people should fix their queries instead of rebuilding the index periodically.

  5) In some rare case, rebuilding the index is the right thing, do it. (e.g. archiving old data 
with partition?)
----------------------------------------
Their arguement:
  1) Rebuilding index is not costly, and you can do it online.

  2) Database become slow again? Just rebuild the index again!

  3) Some query run faster. Don't have to understand why. It just run faster.

  4) Rebuild the index is easy, fixing the queries is hard.  
----------------------------------------

 


Followup   April 19, 2006 - 5pm Central time zone:

1) did not say that...

2) in most all but the rare degenerate cases yes

3) if the index wants to be wide and you make it skinny, it'll take effort to make it wide again.

4) did not say that...  I probably did say "people should fix their queries" <period>.  Don't see 
any relation to rebuilding index necessarily.

5) "sweeper indexes" (date column populated with sysdate, id column populated by sequence) where 
you delete all/most of the old data over time and frequently ask for the "lowest value(s)" could 
benefit from rebuilds/coalesces IF you cannot permanently solve the problem via some physical 
structure that takes care of this (like partitioning)


1) the rebuild is just one step of the process...
2) see above
3) 
4) but doesn't necessarily fix anything 

2 stars When to rebuild bitmap indexes   April 25, 2006 - 8pm Central time zone
Reviewer: Fat Geek from Auckland NZ
Today I had an issue when I was approached because a DW load had failed, the situation appeared 
obvious - tablespace couldn't extend due to a company directive that datafiles be no larger than 
2gb in size (I wont go into that). However on closer observation I noticed that the bitmap indexes 
were huge. I rebuilt them and the tablespace is now only 65% full.

I'm aware that some loads are poorly written and can result in large bitmap indexes. Rather than 
waiting for them to fail, I'd like to be able to tell which bitmap indexes needed rebuilding. 
Looking at size alone doesn't work - some are genuinely large.

Is there a way of telling when a bitmap index is blown out and needs rebuilding? 


Followup   April 26, 2006 - 12am Central time zone:

just look at the loads - if they do slow by slow processing (row by row), the bitmaps will be huge, 
if they do large direct path loads, the bitmaps will be maintained efficiently.

You only have to look at the load methodology to decide if the bitmaps should be disabled, then 
table loaded and then rebuilt. 

3 stars Rebuilding indexes   April 26, 2006 - 5pm Central time zone
Reviewer: Fat Geek from Auckland NZ
OK, I've done that and identified a couple of loads that need fixing; but there are some large 
bitmaps I've found that are over a year old and have loads that disable and rebuild the bitmaps so 
I suspect that a predecessor has started on the same process, fixed future loads but not rebuilt 
historic blown indexes.

This does make it a space reclaiming process rather than an improvement process but I'd like to get 
them rebuilt as it makes sizing for the ongoing migration from Solaris/Sparc/8i to Linux/Intel/9i 
(and a subsequent upgrade to 10g) more accurate.

Is there a query that can be run that gives a hint that the index needs reviewing? 


Followup   April 27, 2006 - 2pm Central time zone:

not beyond looking for "really big bitmaps, that seem bigger than they should" 

2 stars Rebuilding bitmap indexes   May 1, 2006 - 5pm Central time zone
Reviewer: Fat Geek from Auckland NZ
I found two methods of ferreting out bitmap indexes that benefited from a rebuild. Neither are 
guaranteed 100% accurate (or even 80%) but were useful, given the huge number of indexes in a data 
warehouse.

1. Bitmap index partitions that were larger than thier matching table partitions (we have partition 
naming standards so I could run that comparison) benefitted from a rebuild.

2. Bitmap indexes that were blown tended to have a high AVG_DATA_BLOCKS_PER_KEY.

These both were pretty reliable at finding blown indexes but didn't get all of them. However I 
found that they pointed me at areas of concern.
 


5 stars create index   June 11, 2006 - 9am Central time zone
Reviewer: mohannad from jordan
hi
i have a table named car_info with the following fields
car_no,car_owner_no,car_model,car_value,......
i usally user the folowing queries for ths table 
1.select * from car_info where car_no = values
2.select * from owner , car_info where car_info.car_owner_no = owner.owner_no
and car_no = value
3.select * from car_info
where car_mode LARGER THAN values and CAR_MODEL LARGER THEN VALUES
for the first query i create an index on the car_no filed
and for the 
second query i create three indexes on these fields car_owner_no,owner_no.
so my question is what is the best approach to make the third query faster (what indexes should i 
create and why).

 


Followup   June 11, 2006 - 11am Central time zone:

the only answer is "it depends"

but it seems strange to say "where car_model > :x" - card_model is a surrogate key isn't it.  why 
would you do that?


you would have to ask yourself "which will likely (stress LIKELY) return less?  where car_mode > 
:x, or, where car_model > :x.  Which ever one in general would likely return less - that dictates 
which I would pref to have on the leading edge of my index"

and the index would be on both columns.  It is the order you need to determine. 

5 stars 90-10 splits example from R. Foote   August 1, 2006 - 5am Central time zone
Reviewer: yohann from france
Hi Tom,
Document from Richard Foote is very good.
But there is one thing I don't understand with "90-10 splits" is : what is the influence of the 
commit inside or out of the insert loop?
with commit out of the loop: 
SQL> select lf_blks, pct_used from index_stats;
LF_BLKS PCT_USED
---------- ----------
19 94

with commit in the loop:
SQL> select lf_blks, pct_used from index_stats;
LF_BLKS PCT_USED
---------- ----------
36 51

could you explain please why committing after each insert makes a difference.
Thanks
 


Followup   August 1, 2006 - 7am Central time zone:

I believe he was pointing out an odd "product issue" with 9i there. Not something that was supposed 
to happen.



ops$tkyte%ORA10GR2> create table t ( id number, value varchar2(10) );

Table created.

ops$tkyte%ORA10GR2> create index t_idx on t(id);

Index created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> begin
  2     for i in 1 .. 10000
  3     loop
  4        insert into t values (i,'xxxxx' );
  5        commit;
  6     end loop;
  7  end;
  8  /

PL/SQL procedure successfully completed.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> analyze index t_idx validate structure;

Index analyzed.

ops$tkyte%ORA10GR2> select lf_blks, pct_used from index_stats;

                %
   LF_BLKS   Used
---------- ------
        19   94.0
 

5 stars another question whith del_lf_rows   August 2, 2006 - 10am Central time zone
Reviewer: yohann from france
Thank you very much. I tested: it always happens in 9i but nomore in 10g.

another question:
I read so many web pages about the advice of rebuilding index when you reach a ratio 
del_lf_rows/lf_rows. I'm very confused because i think it's a bad rule.
I tried the approach of Richard Foote with showing that del_lf_rows is not a good metric for 
showing fragmentation:
SQL> begin
  2  for i in 1..1000
  3  loop
  4  insert into t values(i);
  5  end loop;
  6  end;
  7  /
SQL> analyze index t_idx validate structure;
Index analyzed.

SQL> select lf_rows, del_lf_rows from index_stats;
   LF_ROWS DEL_LF_ROWS
---------- -----------
      1000           0

SQL> delete from t where x<540;
539 rows deleted.

SQL> delete from t where x between 541 and 999;
459 rows deleted.

SQL> analyze index t_idx validate structure;
Index analyzed.

SQL> select lf_rows, del_lf_rows from index_stats;
   LF_ROWS DEL_LF_ROWS
---------- -----------
      1000         998

NOW IT'S TIME TO REBUILD , NO? BUT...
SQL> insert into t values(1);
1 row created.

SQL> analyze index t_idx validate structure;
Index analyzed.

SQL> select lf_rows, del_lf_rows from index_stats;
   LF_ROWS DEL_LF_ROWS
---------- -----------
       462         459

SQL> insert into t values(700);
1 row created.

SQL> analyze index t_idx validate structure;
Index analyzed.

SQL> select lf_rows, del_lf_rows from index_stats;
   LF_ROWS DEL_LF_ROWS
---------- -----------
         4           0

with the rule, it's nomore time to reorganize; however , I've only inserted 2 rows, and there's 
always 2 blocks almost empty as treedump shows it:
branch: 0x100027c 16777852 (0: nrow: 2, level: 1)
   leaf: 0x100027e 16777854 (-1: nrow: 2 rrow: 2)
   leaf: 0x100027f 16777855 (0: nrow: 2 rrow: 2)


Tom, was it a fair example or something's wrong with my argument?

Thanks 


Followup   August 2, 2006 - 12pm Central time zone:

... I'm very confused because i think it's a bad rule. ...

You are not confused, you are correct.


Not only will that rule flag indexes as being in need of a rebuild when they aren't, they won't 
catch those that are!

see my example above which includes:

ops$tkyte@ORA9IR2> select lf_rows, del_lf_rows from index_stats;
 
   LF_ROWS DEL_LF_ROWS
---------- -----------
      6505         194

(that index was in need of a coalesce/rebuild) 

5 stars Rebuild Index Performance   January 21, 2007 - 3pm Central time zone
Reviewer: PRS from USA
Tom,
  We do the rebuild of index on a very large weekly partition table. Table is having market data. We receive 50 million rows per day and it is a weekly partition.
  We now have only 4 days of data and it takes 2 hrs to rebuild the indexe. We are on ORACLE 9i (9.2.0.7 - 64 bit) and we have E2900 SERVER (24 cpu, 96gb ram).
  Is there any way to improve the performance from 2 Hrs to less time??? Any pointers are appreciated. Are there INIT.ORA parameters we need to evaluate?
  Please let me know if you need any other information related to database?

Thanks,
PRS

5 stars When the index has been rebuilt successfully why am i getting the following error.   February 15, 2007 - 9am Central time zone
Reviewer: A reader from VIRGINIA,USA
09:21:00 sonardba@SONARP.CLT.NASD.COM> set serveroutput on
09:21:08 sonardba@SONARP.CLT.NASD.COM> set echo on
09:22:00 sonardba@SONARP.CLT.NASD.COM> ALTER TABLE NEWS_STORY MODIFY PARTITION NEWS_STORY_P200612 REBUILD UNUSABLE LOCAL INDEXES;

Table altered.

Elapsed: 00:00:00.00
09:24:29 sonardba@SONARP.CLT.NASD.COM> alter index idx_news_story rebuild partition newS_story_p200612;

Index altered.

Elapsed: 00:00:04.03
09:24:50 sonardba@SONARP.CLT.NASD.COM> SELECT COUNT(*) FROM SONARDBA.NEWS_STORY PARTITION (NEWS_STORY_P200612) ;

COUNT(*)                                             
----------                                             
  259588                                             

Elapsed: 00:00:03.05
09:25:44 sonardba@SONARP.CLT.NASD.COM> SELECT COUNT(*) FROM SONARDBA.NEWS_STORY PARTITION (NEWS_STORY_P200612) WHERE contains (STORY_body_bk ,'removed')>0
09:25:51  2 /
SELECT COUNT(*) FROM SONARDBA.NEWS_STORY PARTITION (NEWS_STORY_P200612) WHERE contains (STORY_body_bk ,'removed')>0
*
ERROR at line 1:
ORA-29954: domain index partition is marked LOADING/FAILED/UNUSABLE


Elapsed: 00:00:00.02
09:25:53 sonardba@SONARP.CLT.NASD.COM> spool off;


Followup   February 16, 2007 - 10am Central time zone:

so, what is the status of that index
4 stars status of the index is unusable   February 16, 2007 - 5pm Central time zone
Reviewer: A reader from virginia usa
I beleive if rebuilding of the index is successfull then
the index status should be valid/usable, am I intepreting something wrongly?


Thanks Tom!



Followup   February 18, 2007 - 8am Central time zone:

if you give me an entire example from start to finish that I can run on my machine, I'll be glad to explain to you what happened. As it is, we just have a snippet of a bit of stuff and no details as how to arrive there.
3 stars index reorg on high db file sequential read?   March 1, 2007 - 5pm Central time zone
Reviewer: ignorant 
Hi Tom,
I have been reading your invaluable website very carefully but it looks like I might have missed something.
I am trying to identify cases where you would reindex/coalesce indexes. I do not wish to reindex a table unless it has a strong case because it can't be done online (normally anyway).
In that vein, I am looking at this statspack report of a small (1TB) 9i production database -
period = 4pm-8pm
Sessions approx 142.
Load Profile
~~~~~~~~~~~~
                    Per Second    Per Transaction
                      ---------------    ---------------
        Logical reads:        31,947.21        5,352.37
        Block changes:          201.97          33.84
        Physical reads:          590.61          98.95
        Physical writes:          17.30            2.90
              Sorts:          33.55            5.62
          Transactions:            5.97

We are very efficient with our SQL and buffer. Almost everything is found in cache -
Instance Efficiency Percentages (Target 100%)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Buffer Nowait %: 100.00    Redo NoWait %:  100.00
        Buffer Hit  %:  98.16  In-memory Sort %:  100.00
        Library Hit  %: 100.00    Soft Parse %:  98.96
      Execute to Parse %:  99.79      Latch Hit %:  99.94
Parse CPU to Parse Elapsd %:  82.13  % Non-Parse CPU:  99.87

Shared Pool Statistics    Begin  End
                    ------ ------
        Memory Usage %:  73.30  78.03
  % SQL with executions>1:  97.50  96.91
% Memory for SQL w/exec>1:  88.67  86.23

The sorts are also happening in memory so that is not an issue.
However our top 5 events are ¿
Top 5 Timed Events
~~~~~~~~~~~~~~~~~~                                  % Total
Event                              Waits  Time (s) Ela Time
-------------------------------------------- ------------ ----------- --------
sbtwrite2                          2,533,050  130,025  64.86
db file sequential read                8,016,019    47,703  23.80
CPU time                                    21,742  10.85
sbtinfo2                              12      190    .09
log file parallel write                  167,913      177    .09

sbtwrite2 is the backup to tape. That will take whatever it has to. The other wait here ¿db file sequential read¿.
We have 8,016,019 waits in total or 580 waits/sec!
This means that we have 98.5% of our physical reads have to wait.
This is very high.
To tune this, it seems to me that I should be looking at inefficient indexes that are being scanned repeatedly. I used a lot of methods to try to determine that - index size (rough indicator), indexes with most blocks in memory (another rough indicator), comparing clustering factor to blocks vs num_rows (query1 below), most frequently occuring index operations in V$sql_plan (again, rough idea, query2 below). None of these really show me if I can get anything back by coalescing or reindexing something. Also they all seem to give different results. I based a lot of this analysis on SAP note 771929 (need sap login). But after reading this it seems that I should not worry about indexes at all.
Worst come to worst, if the clustering factor is closer to number of rows than number of blocks, then I should rebuild the table not the index. I do not know how much performance gain would I gain by that and it would be an outage so I have to have a strong case for it. So I would avoid it for now.
Other than that I can only watch statspack reports and look for SQL statements that stay up in buffer gets, etc. Here is the query I used to determine cf factor (query 1)-

select i.index_name, i.CLUSTERING_FACTOR cf, t.table_name, t.BLOCKS, t.NUM_ROWS, round(i.CLUSTERING_FACTOR/t.blocks) cf_ratio, t.LAST_ANALYZED
from dba_indexes i, dba_tables t
where i.table_name=t.table_name
and i.CLUSTERING_FACTOR/t.blocks >100 and t.blocks !=0
order by i.CLUSTERING_FACTOR/t.blocks desc

Here is one candidate from the above query -
D010TAB~1  3035765  D010TAB  15340  4021925  198  28-JUL-06
(admittedly the stats are old for this table)

Here is the query I wrote (might be flawed) to see what the most frequently hit indexes in memory are (query2) -
select * from (
select object_name, count(1)
from v$sql_plan
where operation='INDEX' and (options like 'FULL%' or options like 'RANGE%')
group by object_name order by 2 desc)
where rownum < 20

So if not rebuilding/coalescing indexes, what should be the approach to reduce "db file sequential reads"? And if it is looking at coalescing/rebuilding indexes, which of the above approaches would be the proper one to use? Or is this database performing the best it can given the resources?

I wish I could write a test case for the above but I haven't narrowed down the problem enough yet to be able to do that. I guess that's what I really need help with.

Thank you,
ignorant

Followup   March 2, 2007 - 1pm Central time zone:

and I say "so" to the

... We have 8,016,019 waits in total or 580 waits/sec! ..

you had 4 hours, you had lots of users.


100% of your reads should wait - all IO takes measurable time. 100% of the IO's waited. 100% of physical IO's take MEASURABLE TIME!


I'm not seeing anything horrific here. Say you had 100 users, say the waits were evenly distributed, they each had 5.8 seconds of wait time - in 4 hours. Pretty darn amazingly good don't you think.
3 stars io waits   March 2, 2007 - 2pm Central time zone
Reviewer: ignorant 
Thanks Tom, that was succint and to the point -
"100% of your reads should wait - all IO takes measurable time. 100% of the IO's waited. 100% of physical IO's take MEASURABLE TIME!"
makes perfect sense when I think about it... duh!
So I guess the more important factor is how much wait did each user/session face. Your calculation shows 5.8 seconds of wait time in 4 hours. But I am not sure if I can follow the logic. Can you please elaborate a little bit?
Here is what I am thinking.
580 waits/second over 142 sessions comes out to about 4 waits/second for each session.
Going the other way, the total wait is 47,703 seconds. Per hour, that would be = 47,703/4 = 11,925.75 seconds. That spread over 142 sessions would still be 83 seconds. So that tells me that each session had to wait about 83 seconds every hour.
This is still not bad and clearly no case for index/table reorg/coalesce. But I would still appreciate if you could verify my reasoning here.
Thanks again, your insights are better than Oracle Concepts guide. More like concepts guide + thinking :)

Followup   March 4, 2007 - 6pm Central time zone:

verify which reasoning?



4 stars Meta link Note:122008.1   March 2, 2007 - 5pm Central time zone
Reviewer: Ted from PA
Tom,

Can you comment on the metalink Note:122008.1, "Script: Lists All Indexes that Benefit from a Rebuild"?  Is this a script that should be used?

Followup   March 4, 2007 - 6pm Central time zone:

the deleted entries - maybe, but - it will miss many indexes that would benefit from a coalesce/rebuild but don't have a high deleted leaf row count!!!!!

therein lies the problem, it will (for del lf rows) identify some that MIGHT benefit, but it'll miss the vast majority that would - just read this page for an example)

as for height > 4, what if you rebuild and the results are ..... the same...

and for bitmaps - well, no. You might bitmap an almost unique column, you might bitmap a column with 2 values. Then again, if you do single row operations against this table - you would of course never bitmap. One attribute (selectivity) is wholly insufficient to make this decision.


4 stars rebuild index   March 16, 2007 - 2am Central time zone
Reviewer: Suraj Sharma from India
Tom,

We have databases on which STATSPACK was installed and we are collection the data for about a month and delete the data older than a month. The problem is these databases are having space issues all the times with the default tablespace of the PERFSTAT schema (TOOLS.) Whenever we got such space issue our collegues ask us to rebuild the indexes and also it gives some space free.

I am personally not in favor of doing this and never recommend rebuilding of indexes in every week or so. In this case the snapshot is collected in every 15 mins. for statspack.

Please let me know if this is a right approach of rebuilding indexes in every week or so.

Thanks,
Suraj

Followup   March 17, 2007 - 2pm Central time zone:

do the indexes

a) stay small
b) grow back to big in a week


because if you say "b" then I'd ask

"what was the point, it is not like you could use that space for anything else anyway"
5 stars Sparse Indexes and Rebuild   May 8, 2007 - 11am Central time zone
Reviewer: A reader 
Hello Tom,
Thanks for giving oppurtunity to ask on this topic.
Well we had a onsite consultant and from the long list of recommendations he has given to my manager and team after running some assessment reports on our exisitng Oracle 9i Rel 2 Database, which is a 24/7 OLTP Application, That report says this

10.11    Sparse Indexes
When a table ¿ especially the indexed columns ¿ is heavily affected by DML operations the index may 
become fragmented, i.e. the amount of unused space in the index blocks increases. If the index is 
accessed Oracle has to retrieve more index blocks. In general an index should have less leaf blocks 
than the associated table.


Best Practices
¿    Indexes should be checked regularly if they have more leaf blocks than the table.
¿    Reorganize fragmented indexes.
¿    Rebuild indexes online. Rebuilding indexes online does not affect to table base. The following 
advantages will be provide using alter index <name> rebuild online:
o    DMLs are allowed on the base table
o    Although slower compared with coalesce, coalesce cannot be done ¿online¿
o    Base table is only locked in shared mode (as opposed to exclusive mode for offline rebuilds) 
o    Intermediate data is stored changes are recorded in a temporary journal table during the index 
rebuild, which will be used to update the new index at the end of the ONLINE processing.


 Recommendations

¿    Reorganize those indexes where Extra_Blocks is high (potential space to reclaim) and the leaf 
block density is low (i.e., less that 50-60%).

10.12    Sparse Tables

Many delete or update operations on a table over time can produce a sparse table. 
That means that the high water mark (HWM) of that table is representing a multiple of the really 
existing data in the table. During full table scans Oracle reads all blocks up to the High Water 
Mark (HWM). Those tables should be reorganized to improve performance and to need less disk space.


Best Practices
¿    Repair the tables that are commonly subjected to full table scans and have an excessive amount 
of 
wasted space. Resetting the HWM on these tables will result in shorter response times during full 
table scans 
and increased throughput for the system.
¿    A new package DBMS_REDEFINITION allows for online reorganization of tables 
(See Note 177407.1: How to Re-Organize a Table Online for more information and restrictions)
¿    Tables should be checked regularly if they are sparse.
¿    Reorganize sparse tables.
 Recommendations

¿    Review the listed tables for reorganization .


Do you have any script to get list of sparse indexes,Please want to see list of indexes, because the list of indexes he has given us had around 180 indexes from total of 500 indexes in our Application, I know you are 99.999% times against rebuilding indexes,what is your suggestion on this now,

Thanks

Followup   May 10, 2007 - 8pm Central time zone:

we already had these exact same comments elsewhere.


I always stop reading at:

coalesce cannot be done "online"

why?

because coalesce in fact cannot be done OFFLINE - it is an online ONLY operation.



and you would think their report, if it were identifying issues, would have all queries you ever need to find these problems. I mean, they would not tell you about problems you don't actually have right?
4 stars Index Rebuild for transaction table?   July 23, 2008 - 10am Central time zone
Reviewer: LIU GaoYuan from Singapore
Tom,

This morning one developer complained about a query performance:

select * from table_a where txn_timestamp<sysdate-93

The final result is zero row selected after running for two minuts, and the query is using an index 
indexing on txn_timestamp only.

I did an SQL trace and found that the query read about 700MB of the index (1300MB in total).

The developer later confirmed that they had deleted all the data before May 2008. So I did an index 
rebuild and the new index is about 250MB, and the same query finishes in 0.01 second.

My question is, if a transaction table has indexes with transaction date as the first index column, 
and the transaction data is being purged regularly by transaction date, should we "periodically" 
coalesce or rebuild the index? My understanding is this would behave the same as the example of 
indexing on sequence, and the empty blocks in the left-hand would never be reused if the index is 
not coalesced or rebuilt?

Thanks


Followup   July 24, 2008 - 10am Central time zone:

search this site for "sweeper index"


or, just read this page - we talked about it above.
4 stars   July 24, 2008 - 3am Central time zone
Reviewer: LIU GaoYuan from Singapore
Tom,

Re: Index Rebuild for transaction table

With reference to Richard Foote's article Oracle B-Tree Index Internals: Rebuilding The Truth, 
Richard Foote comments that "Fully emptied blocks are placed on freelist and recycled (although 
remain in the index structure)".

My own test shows that 
1) Oracle will still scan those fully emptied blocks, or "Empty Blocks Not Unlinked" in Richard's 
article.
2) The fully emptied blocks will be reused when new data is inserted.

To avoid performance surprise, a coalesce or rebuild would be helpful if there are huge number of 
fully emptied blocks in the index.

Thanks


Followup   July 24, 2008 - 10am Central time zone:

you are both correct. Yes, the fully emptied blocks are reused when new data is inserted - fully emptied blocks therefore are placed on the freelist and recycled.

only for this "sweeper" index where you DO the actual type of query that causes an issue - it is a rather rare case, and typically only happens on a date column (eg: primary keys populated by a sequence have the same issue in the case of a purge, but you typically never range scan on them like that)
5 stars Basic question on indexes --   September 5, 2008 - 5pm Central time zone
Reviewer: Apurva from nyc
Hi Tom,

Hope you are doing great. I have a question to ask --

If I have a table with indexes defined on it, and I perform some insert/delete operations on the 
table (with index defined). Would the B Tree/Bitmap index(s) adjust itself to account for the 
freshly inserted/deleted records?

Would rebuilding the indexes after insert/delete operations ensure that the index is fresh again?

Or, would you recommend that we drop and recreate indexes after insert/delete operations (something 
we don't want to do)?

Thanks a lot for your advice


Followup   September 8, 2008 - 8am Central time zone:

... Would the B Tree/Bitmap index(s)
adjust itself to account for the freshly inserted/deleted records?
...

yes.

... Would rebuilding the indexes after insert/delete operations ensure that the
index is fresh again?
...

do not even remotely think about considering this - NO you do not do that.

.. Or, would you recommend that we drop and recreate indexes after insert/delete
operations (something we don't want to do)?
....

NO, do not do that.

5 stars Thanks a lot Tom   September 8, 2008 - 10am Central time zone
Reviewer: A reader 


3 stars Space Saving   September 8, 2008 - 12pm Central time zone
Reviewer: Kv from INDIA
Hi Tom,

I know for sure that the B*tree indexes don't need a rebuild in their life time. However we have a 
index based on Seqience number and we have deleted millions of rows from the billion row table.

This kind of indexes need rebuild so that the Left hand side brown leaves just goes away and the 
index becomes compact. this way we will also ensure that the index rasnge scans are faster.

Can you please tell me how to calculate the savings in space without actually re-building the 
index. Is that possible.

Thanks


Followup   September 8, 2008 - 4pm Central time zone:

... I know for sure that the B*tree indexes don't need a rebuild in their life
time. ...

no one is saying that either. There are special cases where a coalesce or rebuild would be called for. Most times - no, rare special cases - yes.


... This kind of indexes need rebuild so that the Left hand side brown leaves just
goes away and the index becomes compact. this way we will also ensure that the
index rasnge scans are faster.
....

that is only true if you delete MOST but not ALL of the left hand (old values), if you purge all of the old values - we move the leaf blocks from the left to the right as needed.

and it only affects a very special range scan - one that starts from the very far left - most range scans would NOT be affected.



...Can you please tell me how to calculate the savings in space without actually
re-building the index. Is that possible.

...

how many rows per leaf block could fit in a newly build index (take some of your data and calculate that)

now, how many rows do you have?
how many leaf blocks do you have?

what percentage of rows to blocks do you have now versus what a 'fresh' one would?

there is your 'savings'
3 stars Index not used   September 15, 2008 - 1pm Central time zone
Reviewer: Maverick 
Tom, I have a small confusion going on with my table indexes:
  I have a table 'X' and has a column fk_case_id [foreign key to another table]
I have an index built on this column 
   idx_caseid[fk_case_id]
I have another index using this and another column
   idx_case_date[fk_case_id,case_date]

When I issue a query like this:
  Select * from X where fk_case_id=1

my plan shows it is always doing a FFS on idx_case_date and not using idx_caseid at all.

Not sure why idx_caseid is not used? I checked by dropping idx_case_date and now it's doing a full 
table scan [only 1% of data has fk_case_id=1 in this table]

I checked index statistics and 
  idx_caseid has the following:
       Leaf_blocks               1041
       Distinct keys              812
       Avg leaf blocks per key      1
       Avg Data blocks per key    422

  idx_case_date has the following:
       Leaf_blocks                1555
       Distinct keys           502,952
       Avg leaf blocks per key       1
       Avg Data blocks per key       1

[Not sure these statistics are of any relevance with my problem]..

Can you point me any reasons why Oracle wouldn't use idx_caseid but instead prefers to use 
idx_case_date?

Thanks

       


Followup   September 16, 2008 - 10pm Central time zone:

no create tables
no look


not even a plan, no example of anything.

probably an implicit conversion - but you give us no clues.... :(
3 stars Here is the missing information   September 18, 2008 - 9am Central time zone
Reviewer: Maverick 
Sorry for not giving table information. Here are more details


SET DEFINE OFF;
CREATE TABLE case_data 
(
  ID                NUMBER(10),
  FK_CASELOAD_ID    NUMBER(10),
  CASE_NUMBER       NUMBER(10),
  ASSIGNED_DATE     DATE,
  STAFF_ID          NUMBER(10),
  AGENCY_ID         NUMBER(10),
  TRANSFERRED_DATE  DATE,
  CONSTRAINT PK_CASELOAD
 PRIMARY KEY
 (ID),
  CONSTRAINT FK_CASELOAD_CASE_LOADS 
 FOREIGN KEY (FK_CASELOAD_ID) 
 REFERENCES CASE_LOADS (ID),
  CONSTRAINT FK_CASELOAD_REASON 
)
NOLOGGING 
NOCOMPRESS 
NOCACHE
NOPARALLEL
MONITORING;



CREATE INDEX IDX_CASELOAD_CN_TRDATE ON case_data 
(CASE_NUMBER, TRANSFERRED_DATE, FK_CASELOAD_ID)
LOGGING
NOPARALLEL;


CREATE INDEX IDX_CASELOAD_CASELOADID ON case_data 
(FK_CASELOAD_ID)
LOGGING
NOPARALLEL;

select count(*) from case_data;

count(*)
--------
502954



set autotrace on; 

select * from case_data
where fk_caseload_id=5;


1042 rows selected.

Execution Plan
----------------------------------------------------------
   0       SELECT STATEMENT Optimizer Mode=ALL_ROWS (Cost=587 Card=1 K Bytes=41 K)
   1    0    TABLE ACCESS FULL TEST.CASE_DATA (Cost=587 Card=1 K Bytes=41 K)

Statistics
----------------------------------------------------------
          0  recursive calls
          0  physical write total multi block requests
          0  gcs messages sent
          0  db block gets from cache
          0  redo entries
          0  java session heap collected bytes
          1  cursor authentications
          0  queries parallelized
          0  Parallel operations not downgraded
          0  Parallel operations downgraded to serial
       1042  rows processed


I do not understand, out of 500K rows, i'm getting only 1042 rows and still it's not using index.


So, I forced it with a hint:

set autotrace on; 

select /*+ index(idx_caseload_caseloadid) */ * from case_data
where fk_caseload_id=5;

Still i get  the same exact plan.

Now I am selecting just one column form the entire table:

set autotrace on; 

select case_number from case_data
where fk_caseload_id=5;


This is the plan I get:

1042 rows selected.

Execution Plan
----------------------------------------------------------
   0       SELECT STATEMENT Optimizer Mode=ALL_ROWS (Cost=359 Card=1 K Bytes=11 K)
   1    0    INDEX FAST FULL SCAN CMS.IDX_CASELOAD_CN_TRDATE (Cost=359 Card=1 K Bytes=11 K)

Statistics
----------------------------------------------------------
          1  recursive calls
          0  physical write total multi block requests
          0  gcs messages sent
          0  db block gets from cache
          0  redo entries
          0  java session heap collected bytes
          0  cursor authentications
          0  queries parallelized
          0  Parallel operations not downgraded
          0  Parallel operations downgraded to serial
       1042  rows processed

It somehow using a different index instead of the one I am expecting[??] idx_caseload_caseloadid.

Where is the problem, Tom?


Followup   September 18, 2008 - 11am Central time zone:

what version and what are you using to run the query,

use dbms_xplan to display the output of the plan if you are using 9i - better information.

Those statistics - what is up with them - none of the useful ones are present. Just use sqlplus please.
3 stars Sorry again !!   September 18, 2008 - 4pm Central time zone
Reviewer: Maverick from US
I keep missing important information.

Version Oracle 10g: I was using TAOD tool to run these queries.
But here is the SQLPLUS Version:

SQL> cl scr
SQL> explain plan for
  2  select * from case_data where fk_caseload_id=5;

Explained.

SQL> select * table(dbms_xplan.display);
select * table(dbms_xplan.display)
         *
ERROR at line 1:
ORA-00923: FROM keyword not found where expected 


SQL> c/table/from table
  1* select * from table(dbms_xplan.display)
SQL> /

PLAN_TABLE_OUTPUT                                                               
--------------------------------------------------------------------------------
Plan hash value: 779626952                                                      
                                                                                
--------------------------------------------------------------------------------
--                                                                              
                                                                                
| Id  | Operation         | Name         | Rows  | Bytes | Cost (%CPU)| Time    
 |                                                                              
                                                                                
--------------------------------------------------------------------------------
--                                                                              
                                                                                

PLAN_TABLE_OUTPUT                                                               
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |              |  1313 | 42016 |   587   (4)| 00:00:08
 |                                                                              
                                                                                
|*  1 |  TABLE ACCESS FULL| CASE_DATA |  1313 | 42016 |   587   (4)| 00:00:08
 |                                                                              
                                                                                
--------------------------------------------------------------------------------
--                                                                              
                                                                                
                                                                                
Predicate Information (identified by operation id):                             

PLAN_TABLE_OUTPUT                                                               
--------------------------------------------------------------------------------
---------------------------------------------------                             
                                                                                
   1 - filter("FK_CASELOAD_ID"=5)                                               

13 rows selected.

SQL> select count(*) from case_data;

  COUNT(*)                                                                      
----------                                                                      
    502954                                                                      

SQL> explain plan for
  2  select case_number from case_data
  3  where fk_caseload_id=5;

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT                                                               
--------------------------------------------------------------------------------
Plan hash value: 2061868224                                                     
                                                                                
--------------------------------------------------------------------------------
---------------                                                                 
                                                                                
| Id  | Operation            | Name                   | Rows  | Bytes | Cost (%C
PU)| Time     |                                                                 
                                                                                
--------------------------------------------------------------------------------
---------------                                                                 
                                                                                

PLAN_TABLE_OUTPUT                                                               
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                        |  1313 | 11817 |   359   
(5)| 00:00:05 |                                                                 
                                                                                
|*  1 |  INDEX FAST FULL SCAN| IDX_CASELOAD_CN_TRDATE |  1313 | 11817 |   359   
(5)| 00:00:05 |                                                                 
                                                                                
--------------------------------------------------------------------------------
---------------                                                                 
                                                                                
                                                                                
Predicate Information (identified by operation id):                             

PLAN_TABLE_OUTPUT                                                               
--------------------------------------------------------------------------------
---------------------------------------------------                             
                                                                                
   1 - filter("FK_CASELOAD_ID"=5)                                               

13 rows selected.

SQL> spool off


Hope this helps [in helping me]. Please  let me know in case of any more information

Thanks,


Followup   September 18, 2008 - 9pm Central time zone:

can you "prove" the indexes are as you say.

do this

create table t as select * from case_data;
create the indexes
do the query


I believe there is something in the way you are creating the index that does not relate to what you say you did.

so, show us the work from start to finish

1 stars ??   September 19, 2008 - 8am Central time zone
Reviewer: Maverick 
Tom, Not sure I followed your question!!
I think that's what I did in my earlier post. If you look at it, I have put in the create 
statements for Table and Indexes. That shows how I am creating indexes. I have provided Plan 
generated by auto trace and also by Explain plan. 

If you use those statements and recreate at your end, does it not show the way I am getting it?



Followup   September 19, 2008 - 9am Central time zone:

all I asked was for you to step by step reproduce this.

Anyway, it is likely due to a poor clustering factor. If the case_data arrives randomly over time - so that each case data record you need is on a different database block - we would tend to (rightly so) avoid the index.

If the data were colocated, we would use the index. Consider, in the following - note how the case data arrives - none of the "5" values are on the same block the first time around:



ops$tkyte%ORA10GR2> create table case_loads( id number(10) primary key );

Table created.

ops$tkyte%ORA10GR2> insert into case_loads
  2  select level from dual connect by level <= 384
  3  /

384 rows created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> CREATE TABLE case_data
  2  (
  3    ID                NUMBER(10),
  4    FK_CASELOAD_ID    NUMBER(10),
  5    CASE_NUMBER       NUMBER(10),
  6    ASSIGNED_DATE     DATE,
  7    STAFF_ID          NUMBER(10),
  8    AGENCY_ID         NUMBER(10),
  9    TRANSFERRED_DATE  DATE,
 10    CONSTRAINT PK_CASELOAD PRIMARY KEY (ID),
 11    CONSTRAINT FK_CASELOAD_CASE_LOADS
 12   FOREIGN KEY (FK_CASELOAD_ID)
 13   REFERENCES CASE_LOADS (ID)
 14  );

Table created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> insert into case_data
  2  select level, mod(level,384)+1, level, sysdate, level, level, sysdate
  3    from dual connect by level <= 502954
  4  /

502954 rows created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> CREATE INDEX IDX_CASELOAD_CASELOADID ON case_data (FK_CASELOAD_ID);

Index created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> exec dbms_stats.gather_table_stats( user, 'CASE_DATA' );

PL/SQL procedure successfully completed.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> select a.num_rows, a.blocks, b.clustering_factor,
  2         (select count(distinct dbms_rowid.rowid_block_number(rowid)) from case_data where 
fk_caseload_id=5) cnt_blocks
  3    from user_tables a, user_indexes b
  4   where a.table_name = 'CASE_DATA'
  5     and b.index_name = 'IDX_CASELOAD_CASELOADID'
  6  /

  NUM_ROWS     BLOCKS CLUSTERING_FACTOR CNT_BLOCKS
---------- ---------- ----------------- ----------
    501422       3142            502954       1310

the clustering factor is near the number of rows in the table - large range scans will not be 
efficient against this data, it will have to visit a single block per row retrieved - we can see 
that the "5" data is on 1310 separate blocks - we'll have to use single block IO 1310 times to 
retrieve this data


ops$tkyte%ORA10GR2> set autotrace traceonly
ops$tkyte%ORA10GR2> select * from case_data where fk_caseload_id=5;

1310 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 2422329801

-------------------------------------------------------------------------------
| Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |           |  1302 | 50778 |  1006   (5)| 00:00:05 |
|*  1 |  TABLE ACCESS FULL| CASE_DATA |  1302 | 50778 |  1006   (5)| 00:00:05 |
-------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("FK_CASELOAD_ID"=5)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
       3236  consistent gets
          0  physical reads
          0  redo size
      48224  bytes sent via SQL*Net to client
       1341  bytes received via SQL*Net from client
         89  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       1310  rows processed

ops$tkyte%ORA10GR2> select /*+ index( case_data IDX_CASELOAD_CASELOADID ) */ * from case_data where 
fk_caseload_id=5;

1310 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 1867324150

----------------------------------------------------------------------------------------------------
---
| Id  | Operation                   | Name                    | Rows  | Bytes | Cost (%CPU)| Time   
  |
----------------------------------------------------------------------------------------------------
---
|   0 | SELECT STATEMENT            |                         |  1302 | 50778 |  1315   (1)| 
00:00:07 |
|   1 |  TABLE ACCESS BY INDEX ROWID| CASE_DATA               |  1302 | 50778 |  1315   (1)| 
00:00:07 |
|*  2 |   INDEX RANGE SCAN          | IDX_CASELOAD_CASELOADID |  1306 |       |     5   (0)| 
00:00:01 |
----------------------------------------------------------------------------------------------------
---

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("FK_CASELOAD_ID"=5)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
       1403  consistent gets
          0  physical reads
          0  redo size
      48224  bytes sent via SQL*Net to client
       1341  bytes received via SQL*Net from client
         89  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       1310  rows processed

ops$tkyte%ORA10GR2> set autotrace off

the cost of the full scan using multi-block reads is less than the cost of tons of single block 
reads in this case, if the data were organized on disk differently:

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> create table t as select * from case_data;

Table created.

ops$tkyte%ORA10GR2> truncate table case_data;

Table truncated.

ops$tkyte%ORA10GR2> insert /*+ append */ into case_data select * from t order by fk_caseload_id;

502954 rows created.

ops$tkyte%ORA10GR2> exec dbms_stats.gather_table_stats( user, 'CASE_DATA', cascade=> true );

PL/SQL procedure successfully completed.

ops$tkyte%ORA10GR2> select a.num_rows, a.blocks, b.clustering_factor,
  2         (select count(distinct dbms_rowid.rowid_block_number(rowid)) from case_data where 
fk_caseload_id=5) cnt_blocks
  3    from user_tables a, user_indexes b
  4   where a.table_name = 'CASE_DATA'
  5     and b.index_name = 'IDX_CASELOAD_CASELOADID'
  6  /

  NUM_ROWS     BLOCKS CLUSTERING_FACTOR CNT_BLOCKS
---------- ---------- ----------------- ----------
    504905       3142              3455          9

now the clustering factor is near the number of blocks in the table, large range scans are 
efficient - we can see that all of our "5" data is on 9 blocks...


ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> set autotrace traceonly
ops$tkyte%ORA10GR2> select * from case_data where fk_caseload_id=5;

1310 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 1867324150

----------------------------------------------------------------------------------------------------
---
| Id  | Operation                   | Name                    | Rows  | Bytes | Cost (%CPU)| Time   
  |
----------------------------------------------------------------------------------------------------
---
|   0 | SELECT STATEMENT            |                         |  1391 | 54249 |    16   (0)| 
00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| CASE_DATA               |  1391 | 54249 |    16   (0)| 
00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_CASELOAD_CASELOADID |  1391 |       |     6   (0)| 
00:00:01 |
----------------------------------------------------------------------------------------------------
---

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("FK_CASELOAD_ID"=5)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
        192  consistent gets
          0  physical reads
          0  redo size
      48224  bytes sent via SQL*Net to client
       1341  bytes received via SQL*Net from client
         89  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       1310  rows processed

and the index is used naturally


Physical organization counts, a lot - Not knowing your data, I'm totally guessing, but probably the case data arrives out of order and you are using a heap organized table and the data is scattered all over the place...

What could you do? Maybe a b*tree cluster would be called for, to keep all of the related case data together. for example:

ops$tkyte%ORA10GR2> create table case_loads( id number(10) primary key );

Table created.

ops$tkyte%ORA10GR2> insert into case_loads
  2  select level from dual connect by level <= 384
  3  /

384 rows created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> create cluster case_data_cluster ( fk_caseload_id number(10) ) size 8k;

Cluster created.

ops$tkyte%ORA10GR2> create index case_data_cluster_idx on cluster case_data_cluster;

Index created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> CREATE TABLE case_data
  2  (
  3    ID                NUMBER(10),
  4    FK_CASELOAD_ID    NUMBER(10),
  5    CASE_NUMBER       NUMBER(10),
  6    ASSIGNED_DATE     DATE,
  7    STAFF_ID          NUMBER(10),
  8    AGENCY_ID         NUMBER(10),
  9    TRANSFERRED_DATE  DATE,
 10    CONSTRAINT PK_CASELOAD PRIMARY KEY (ID),
 11    CONSTRAINT FK_CASELOAD_CASE_LOADS
 12   FOREIGN KEY (FK_CASELOAD_ID)
 13   REFERENCES CASE_LOADS (ID)
 14  )
 15  cluster case_data_cluster(fk_caseload_id);

Table created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> insert into case_data
  2  select level, mod(level,384)+1, level, sysdate, level, level, sysdate
  3    from dual connect by level <= 502954
  4  /

502954 rows created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> exec dbms_stats.gather_table_stats( user, 'CASE_DATA', cascade=>true );

PL/SQL procedure successfully completed.

ops$tkyte%ORA10GR2>


ops$tkyte%ORA10GR2> set autotrace traceonly
ops$tkyte%ORA10GR2> select * from case_data where fk_caseload_id=5;

1310 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 3427366092

----------------------------------------------------------------------------------------------
| Id  | Operation            | Name                  | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                       |  1303 | 50817 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS CLUSTER| CASE_DATA             |  1303 | 50817 |     2   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN  | CASE_DATA_CLUSTER_IDX |     1 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("FK_CASELOAD_ID"=5)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
         97  consistent gets
          0  physical reads
          0  redo size
      48224  bytes sent via SQL*Net to client
       1341  bytes received via SQL*Net from client
         89  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       1310  rows processed

ops$tkyte%ORA10GR2> set autotrace off
ops$tkyte%ORA10GR2>


in this case, even though we loaded the data "out of order", the btree cluster put it all back together - all of the "5"'s are colocated.

4 stars Thanks a bunch!!   September 19, 2008 - 11am Central time zone
Reviewer: Maverick 
That was really useful.I'll give it a try and see if it changes the plan like you mentioned.

As far as data coming in random order, we are currently migrating our existing data into new 
system. Depending on the problems we find, we are doing this multiple times.
we usually do a "insert /* append */ " into this table from the source [which is in a staging area]
Do you think this migration is causing data to go in different blocks and Creating the cluster is 
the way to go for this? 

Thanks a lot for all your help


Followup   September 19, 2008 - 4pm Central time zone:

it would depend on how the data is ordered in the first place - select * from source - did source have the data arrive randomly or out of order.

creating a cluster is something to CONSIDER.

along with everything else - I'm sure you execute many other queries, if you organize the data by this foreign key - they might be affected (the old whack a mole syndrome)
2 stars organizing segments   September 22, 2008 - 4am Central time zone
Reviewer: A reader 
greetings thomas,

I have a table that have a lot of insertions and deletions, and after some time of heavy insert and 
delete, the system goes slow, so we move the table and rebuild its indexes and the system goes 
fast, so i am planning to make a job that organize this table every night or every week.

What do you think.

Thanks.


Followup   September 22, 2008 - 5pm Central time zone:

I think I'd ask myself "what part of this rebuild actually fixed anything - what was slow, and what goes faster, perhaps I don't need to move the table at all, perhaps I don't need to rebuild n-1 index - perhaps there is just one thing that has a large impact and that is all I need to do"

In short, I'd want to understand what about that change causes this massive "good thing" to happen and why. Perhaps I can use a structure (cluster, IOT, partitioning, whatever) to avoid ever having to rebuild or reorganize again.


4 stars Index not used   September 22, 2008 - 9am Central time zone
Reviewer: Maverick 
Tom, I was doing some analysis before I create a cluster for my table CASE_DATA. I ran the query 
you provided to find how many blocks this data is spread into..

I did 'Alter table CASE_DATA move' and found, it went to more blocks instead of reducing the number 
of blocks..

I am not fully aware of this command and just trying after reading about it on the net.

Here is the cut paste from sql*plus:

SQL*Plus: Release 10.2.0.1.0 - Production on Mon Sep 22 08:25:45 2008

Copyright (c) 1982, 2005, Oracle.  All rights reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options

SQL> select a.num_rows, a.blocks, b.clustering_factor,
  2           (select count(distinct dbms_rowid.rowid_block_number(rowid)) from case_data where 
  3                        fk_caseload_id=5) cnt_blocks
  4       from user_tables a, user_indexes b
  5      where a.table_name = 'CASE_DATA'
  6        and b.index_name = 'IDX_CASELOAD_CASELOADID';

  NUM_ROWS     BLOCKS CLUSTERING_FACTOR CNT_BLOCKS
---------- ---------- ----------------- ----------
    502943       2574            343446        755

SQL> alter table case_data move;

Table altered.

SQL> select a.num_rows, a.blocks, b.clustering_factor,
  2           (select count(distinct dbms_rowid.rowid_block_number(rowid)) from case_data where 
  3                        fk_caseload_id=5) cnt_blocks
  4       from user_tables a, user_indexes b
  5      where a.table_name = 'CASE_DATA'
  6        and b.index_name = 'IDX_CASELOAD_CASELOADID';

  NUM_ROWS     BLOCKS CLUSTERING_FACTOR CNT_BLOCKS
---------- ---------- ----------------- ----------
    502943       2574            343446        768

SQL> 
SQL> 

Why does it show more blocks after MOVE? Shouldn't that be few blocks?


Followup   September 23, 2008 - 12pm Central time zone:

you reintroduced the pct free, you unmigrated rows, you fundementally changed the data.

The count(dbms rowid) thing I did counts the head rowid pieces (worked for me since I never updated the rows after insertion - i had no migrated rows) - if you had migrated rows before - your original could could easily be smaller. Also, you reintroduced the pctfree of X% (whatever you had it set to) - so you could easily have moved rows around.

13 blocks is "noise" here, not really significant.

ops$tkyte%ORA10GR2> create table t ( x int, y varchar2(4000) );

Table created.

ops$tkyte%ORA10GR2> insert into t (x) select rownum from all_users;

58 rows created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> select count(distinct dbms_rowid.rowid_block_number(rowid) ) from t;

COUNT(DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID))
---------------------------------------------------
                                                  1

ops$tkyte%ORA10GR2> alter table t move;

Table altered.

ops$tkyte%ORA10GR2> select count(distinct dbms_rowid.rowid_block_number(rowid) ) from t;

COUNT(DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID))
---------------------------------------------------
                                                  1

ops$tkyte%ORA10GR2> update t set y = rpad('*',4000,'*');

58 rows updated.

 obviously, these do not fit on a  block anymore! 
ops$tkyte%ORA10GR2> select count(distinct dbms_rowid.rowid_block_number(rowid) ) from t;

COUNT(DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID))
---------------------------------------------------
                                                  1

we are only counting the head rowid piece, when we reorg the table, we "unmigrate" the rows as 
well

ops$tkyte%ORA10GR2> alter table t move;

Table altered.

ops$tkyte%ORA10GR2> select count(distinct dbms_rowid.rowid_block_number(rowid) ) from t;

COUNT(DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID))
---------------------------------------------------
                                                 58

it takes 58 blocks to hold those rows, not just one, when Y is filled with data


2 stars organizing segments   September 23, 2008 - 2am Central time zone
Reviewer: A reader 
greetings thomas,

and thanks like always.

--In short, I'd want to understand what about that change causes this massive "good thing" to 
happen and why

i did understand what about that change, this table is like a workarea for the whole system, every 
one want something from the system would go to that table and issue an insert and a delete.

--Perhaps I can use a structure (cluster, IOT, partitioning, whatever) to avoid ever having to 
rebuild or reorganize again

I did partition the table, but the same, after the rebuild everything goes fast.


Followup   September 24, 2008 - 3pm Central time zone:

... every one want something from the system would go to that table
and issue an insert and a delete.
...

so, that should not be so bad.

why do you not use a global temporary table - using a permanent table for this is wrong. If you use a global temporary table, they would not delete and the segments would be cleaned up upon commit or session end and you would never need to touch this table again.
3 stars Index not used   September 23, 2008 - 4pm Central time zone
Reviewer: Maverick 
Tom, 
  But my scenario is different. we have migrated data. Ran the query to find number of blocks on 
that table. and did "alter table move" and ran the query again. There was no DML or any other DDL 
took place on that database [not just table, but the database is locked currently]. So if I did 
"Alter table [tablename] Move " shouldn't it reorg the data and reduce number of blocks if they are 
fragmented bad?

I thought we use MOVE to reorganize , but it seems not [I have not much experience with it to even 
comment]. 
So, please give me your thoughts on this command and why it's used or how will it help me reduce 
fragmentation of data ..

Thanks for all your help


Followup   September 24, 2008 - 6pm Central time zone:

did it increase the number of blocks in the table? You didn't show us that, you showed us that the data got more spread out - you don't have an order by on that alter table move (dbms_redefinition would let you do that), so the order of the data is "not deterministic" especially if you use ASSM (automatic segment space management)

You do use move to "reorg", it will compact the table, but you haven't shown it not compacting the table - you showed it possibly moving rows around - but the blocks would be "compact" (10% free by default, unless you changed the pctfree)

if the database is "locked" (whatever that means), how did the data get loaded in the first place... must not have been "locked" at some prior point in time.

alter table move is for

a) moving a table - from tablespace 1 to tablespace 2
b) removing "free space" that has been introduced due to "deletes" not followed by inserts

it does "reorganize" the table, it does "compact it". You have not shown it "uncompacting" the table at all.

I am of the opinion somewhat that there were some modifications at least after you loaded - before you moved (move again, what happens then???)

4 stars index internal pdf -new URL   October 26, 2008 - 3am Central time zone
Reviewer: A reader 
The index internal ppt - refered in many posts above has been moved to this URL, thought it will be 
useful to put it here.

http://bbs.wisky.org/doc/internal.docs/Richard%20Foote-Oracle%20Index%20Internal.pdf



3 stars Update global index   December 31, 2008 - 1am Central time zone
Reviewer: Shivdeep Modi from Noida, India
If i am dropping multiple partitions of a partitioned table with a global indexes, should I use the 
update global index with every alter table drop partition command or with the last command only? Is 
this more efficient rather than using it will all the alter statements?

alter table tab1 drop partition part1;
alter table tab1 drop partition part2;
alter table tab1 drop partition part3 update global indexes;


Followup   January 5, 2009 - 10am Central time zone:

it would be sort of pointless to do it on the 3rd drop.

ops$tkyte%ORA10GR2> CREATE TABLE t
  2  (
  3    dt  date,
  4    x   int,
  5    y   varchar2(30)
  6  )
  7  PARTITION BY RANGE (dt)
  8  (
  9    PARTITION part1 VALUES LESS THAN (to_date('01-jan-2005','dd-mon-yyyy')),
 10    PARTITION part2 VALUES LESS THAN (to_date('01-jan-2006','dd-mon-yyyy')),
 11    PARTITION part3 VALUES LESS THAN (to_date('01-jan-2007','dd-mon-yyyy')),
 12    PARTITION part4 VALUES LESS THAN (to_date('01-jan-2008','dd-mon-yyyy'))
 13  )
 14  /

Table created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> insert into t
  2  select add_months( to_date( '31-dec-2004','dd-mon-yyyy'), mod(rownum,4)*12 ), user_id, 
username
  3    from all_users;

45 rows created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> select 'part1', count(*) from t partition(part1) union all
  2  select 'part2', count(*) from t partition(part2) union all
  3  select 'part3', count(*) from t partition(part3) union all
  4  select 'part4', count(*) from t partition(part4);

'PART   COUNT(*)
----- ----------
part1         11
part2         12
part3         11
part4         11

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> create index t_idx on t(x) global;

Index created.

ops$tkyte%ORA10GR2> select index_name, status from user_indexes where table_name = 'T';

INDEX_NAME                     STATUS
------------------------------ --------
T_IDX                          VALID

ops$tkyte%ORA10GR2> alter table t drop partition part1;

Table altered.

ops$tkyte%ORA10GR2> select index_name, status from user_indexes where table_name = 'T';

INDEX_NAME                     STATUS
------------------------------ --------
T_IDX                          UNUSABLE

ops$tkyte%ORA10GR2> alter table t drop partition part2;

Table altered.

ops$tkyte%ORA10GR2> alter table t drop partition part3 update global indexes;

Table altered.

ops$tkyte%ORA10GR2> select index_name, status from user_indexes where table_name = 'T';

INDEX_NAME                     STATUS
------------------------------ --------
T_IDX                          UNUSABLE



it won't (can't) 'fix' the global indexes on the third drop.


Your index would need to be rebuilt.
3 stars Rebuild Indexes - Analyze Index.. validate structure ?   January 4, 2009 - 6am Central time zone
Reviewer: Harschil Kaparwan from UK
Hi Tom 

Many thanks for enlightening me as always.
I am not going to ask when/why we should rebuild the index. I have gone through articles written by 
you on that.

In order to populate index_stats we need to use:
ANALYZE INDEX <INDEX_NAME> VALIDATE STRUCTURE;

Now questions:

a)We use dbms_stats.schema_gather to get *things* for CBO (with cascade=true)
Now if we use Analyze command , whether stats gathered using dbms_stats for index will be 
overwritten ? 

b) "Analyze" command is deprecated now , then why to use "Analyze" to populate index_stats?

Kind Regards


 


Followup   January 5, 2009 - 11am Central time zone:

In order to populate index_stats we need to use:
ANALYZE INDEX <INDEX_NAME> VALIDATE STRUCTURE;


and don't forget - that'll LOCK that index - it is not an online operation. And if you use the online option - it doesn't populate index_stats...


a) no, they won't be.
b) analyze is deprecated as a means to gather statistics. analyze is used to validate structures still.
2 stars Rebuilding indexes helps   July 3, 2009 - 6am Central time zone
Reviewer: RSah from Ontario
I gather you say rebuilding indexes does not help on performance improvement as every one expects. But in my case i can tell you it gave me 100% performance improvement on a 10+ million record tables. I am not DBA so i cannot pin point what reindexing did. But definitely more than one occassion i asked DBA to rebuild index and it gave expected performance improvement.

Followup   July 6, 2009 - 7pm Central time zone:

Man, the art of critical reading is dead isn't it. It is out the window along with "being able to phrase sensible questions"



RSah - please, take a few moments and point out anywhere on this page where I've said "I gather you say rebuilding indexes does not help on performance improvement as every one expects."

Anywhere, just one reference, that would be great.


What I said were things like "If you can show me measurable performance increases or some other measurable, material benefit --
by all means rebuild."

which leads me to believe - you didn't actually read this page.
3 stars Rebuild index metrix   August 27, 2009 - 4pm Central time zone
Reviewer: A reader 
For all those who question index rebuilds, here is a metric we measured before and after index rebuild.
These measurements were taken on same database, same workload, same day of week, same time of day (all on production 24x7 db). DB_FILE_SEQUENTIAL_READ WAITS before index rebuild = 986,692 (one hour snapshot), DB_FILE_SEQUENTIAL_READ WAITS after rebuild = 49,724 : PHYSICAL READS before rebuild = 369.42, PHYSICAL READS after rebuild = 22.35. This is same code, both snapshots have 64 sessions, near identical Curs/Sess. Why rebuilds improve performance? I/O improvements and less waits.

Followup   August 28, 2009 - 5pm Central time zone:

*perfect*

... here is a metric we measured before and after index rebuild. ...

PERFECT.

If you read my original answer, you'll see that we are in complete and utter agreement. I wrote:


ask them for the performance metrics
they took BEFORE the rebuild and AFTER the rebuild. They won't have any (no
one ever does, no one seems to think about doing that). They will say "it just
goes faster trust me".


You have done what I asked, you have verified that the INDEX you rebuild provides good returns.

And you can use your metric approach to see that that other 99 indexes you have - provide NO such return if they are rebuilt.

So, you have proven that the single index you rebuild

a) provides a return
b) provides the return you were aiming for

perfect.
4 stars What about the Automatic Segment Advisor recommendations   September 3, 2009 - 3pm Central time zone
Reviewer: Mark from Seattle,WA
Tom,

Very interesting thread, thanks.

What are your thoughts on shrinking indexes identified by the automatic segment advisor findings.

select * from table ( DBMS_SPACE.ASA_RECOMMENDATIONS ) where segment_type like '%INDEX%'


Followup   September 4, 2009 - 3pm Central time zone:

It can be

a) a good thing (unlikely in most cases unless it is an index on a sequence field or a date field populated by seq.nextval or sysdate where you delete many of the old records but not all)

b) a non-event, neither good nor bad

c) a bad thing - since the index will just grow again and growing is expensive - but staying the same size costs nothing.
1 stars frequency of execution of CTX_DDL.SYNC_INDEX   November 30, 2009 - 4pm Central time zone
Reviewer: RG 
Hi:
In our application [on Oracle 9i (9.2.0.7.0)] we execute CTX_DDL.SYNC_INDEX every 5 mins (using a 
DBMS_JOB) to synchronize oracle text indexes on VARCHAR2 columns. 
The same job optimizes the indexes at 7 AM, 12 PM and 5 PM to reduce index fragmentation.

The user doesn't want to wait 5 mins to find inserted/updated records in the search result.

I am planning on increasing the frequency of index synchronization to 1 min so that the user does 
not have to wait 5 mins to search inserted/updated records. My main concern was performance and 
based on the information in http://download.oracle.com/docs/html/A95995_01/oraclete.htm it doesn't 
look like performance will be impacted. There will be index fragmentation which happens right now 
anyway and the index optimization at 7 AM, 12 PM and 5 PM should take care of that.

Do you have any comments on this approach? Is there a better way to solve this problem?

Thanks!


Followup   December 1, 2009 - 3am Central time zone:

If you cannot wait 5 minutes, you cannot wait 5 minutes, if you want the index maintained more frequently so that recently modified data is in there - you have to do that.

You can even go with sync on commit if you want, nowadays (and for quite a while) you can make text indexes transactional.

It would utterly depend on information I don't have (size of existing data, transaction workload) as to whether it would be too cumbersome or not - that would be something you would need to test.

Write a Review
 


All information and materials provided here are provided "as-is"; Oracle disclaims all express and implied warranties, including, the implied warranties of merchantability or fitness for a particular use. Oracle shall not be liable for any damages, including, direct, indirect, incidental, special or consequential damages for loss of profits, revenue, data or data use, incurred by you or any third party in connection with the use of this information or these materials.

About Oracle | Legal Notices and Terms of Use | Privacy Statement