Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Mailing Lists -> Oracle-L -> Re: Checking the rebuildability of an index

Re: Checking the rebuildability of an index

From: Connor McDonald <hamcdc_at_yahoo.co.uk>
Date: Wed, 07 Aug 2002 14:16:39 -0800
Message-ID: <F001.004AE300.20020807141639@fatcity.com>


Here is some examples showing re-use of index space with different but "appropriate" values

Example 1: Index space being re-used



SQL> create table test ( p number );

Table created.

SQL> insert into test
  2 select rownum*10
  3 from sys.source$
  4 where rownum < 50000;

49999 rows created.

SQL> create index test_ix on test ( p );

Index created.

SQL> select /*+ FIRST_ROWS */ * from test   2 where rownum < 20
  3 and p > 0;

         P


        10
        20
        30
        40
        50
        60
        70
        80
        90
       100
       110
       120
       130
       140
       150
       160
       170
       180
       190

19 rows selected.

> ====
> So we've got rows with multiples of 10 as values
> ====

SQL> analyze index test_ix validate structure;

Index analyzed.

SQL> select lf_blks, lf_rows, del_lf_rows   2 from index_stats;

   LF_BLKS LF_ROWS DEL_LF_ROWS
---------- ---------- -----------

        55 49999 0

> ====
> And the index is ~ 55 blks
> ====

SQL> delete from test
  2 where mod(trunc(p/10),5) = 0;

9999 rows deleted.

SQL> commit;

Commit complete.

SQL> select /*+ FIRST_ROWS */ * from test   2 where rownum < 20
  3 and p > 0;

         P


        10
        20
        30
        40
        60
        70
        80
        90
       110
       120
       130
       140
       160
       170
       180
       190
       210
       220
       230

19 rows selected.

> ====
> So I've now removed 10k rows, the ones which are
multiples of 50
> ====

SQL> analyze index test_ix validate structure;

Index analyzed.

SQL> select lf_blks, lf_rows, del_lf_rows   2 from index_stats;

   LF_BLKS LF_ROWS DEL_LF_ROWS
---------- ---------- -----------

        55 49999 9999

SQL> insert into test
  2 select rownum*50+5
  3 from sys.source$
  4 where rownum < 10000;

9999 rows created.

SQL> commit;

Commit complete.

SQL> analyze index test_ix validate structure;

Index analyzed.

SQL> select /*+ FIRST_ROWS */ * from test   2 where rownum < 20
  3 and p > 0;

         P


        10
        20
        30
        40
        55
        60
        70
        80
        90
       105
       110
       120
       130
       140
       155
       160
       170
       180
       190

19 rows selected.

> ====
> And I've re-inserted rows which are slightly more
than multiples of 50. They are NEW values but they fit nicely into the space that was deleted
> ====

SQL> select lf_blks, lf_rows, del_lf_rows   2 from index_stats;

   LF_BLKS LF_ROWS DEL_LF_ROWS
---------- ---------- -----------

        55 49999 0

And the index has not grown at all...

So far so good, but what if in the example above, all I do is create the index *BEFORE* I load the data

Example 2: Problems with space



SQL> drop table test;

Table dropped.

SQL> create table test ( p number );

Table created.

SQL> create index test_ix on test ( p );

Index created.

SQL> insert into test
  2 select rownum*10
  3 from sys.source$
  4 where rownum < 50000;

49999 rows created.

SQL> select /*+ FIRST_ROWS */ * from test   2 where rownum < 20
  3 and p > 0;

         P


        10
        20
        30
        40
        50
        60
        70
        80
        90
       100
       110
       120
       130
       140
       150
       160
       170
       180
       190

19 rows selected.

SQL> analyze index test_ix validate structure;

Index analyzed.

SQL> select lf_blks, lf_rows, del_lf_rows   2 from index_stats;

   LF_BLKS LF_ROWS DEL_LF_ROWS
---------- ---------- -----------

        50 49999 0

SQL> delete from test
  2 where mod(trunc(p/10),5) = 0;

9999 rows deleted.

SQL> commit;

Commit complete.

SQL> select /*+ FIRST_ROWS */ * from test   2 where rownum < 20
  3 and p > 0;

         P


        10
        20
        30
        40
        60
        70
        80
        90
       110
       120
       130
       140
       160
       170
       180
       190
       210
       220
       230

19 rows selected.

SQL> analyze index test_ix validate structure;

Index analyzed.

SQL> select lf_blks, lf_rows, del_lf_rows   2 from index_stats;

   LF_BLKS LF_ROWS DEL_LF_ROWS
---------- ---------- -----------

        50 49999 9999

SQL> insert into test
  2 select rownum*50+5
  3 from sys.source$
  4 where rownum < 10000;

9999 rows created.

SQL> commit;

Commit complete.

SQL> analyze index test_ix validate structure;

Index analyzed.

SQL> select /*+ FIRST_ROWS */ * from test   2 where rownum < 20
  3 and p > 0;

         P


        10
        20
        30
        40
        55
        60
        70
        80
        90
       105
       110
       120
       130
       140
       155
       160
       170
       180
       190

19 rows selected.

SQL> select lf_blks, lf_rows, del_lf_rows   2 from index_stats;

   LF_BLKS LF_ROWS DEL_LF_ROWS
---------- ---------- -----------

        99 49999 0

OH NO!!! What has gone wrong? Well, indexes only take notice of pctfree when being built, so our pre-created index will be about 99%+ full. And the values (with the '5' suffix) we are trying to re-insert after deletion have an additional significant digit - and they won't fit! So bingo - more blocks! To prove that its not some problem inherent with the index, we can reverse the example, so that the rows start with a '5' suffix (and hence have more significant digits), delete some, and then insert rows that are multiples of 10

Example 3: Space sorts itself out again



SQL> drop table test;

Table dropped.

SQL> create table test ( p number );

Table created.

SQL> create index test_ix on test ( p );

Index created.

SQL> insert into test
  2 select rownum*10+5
  3 from sys.source$
  4 where rownum < 50000;

49999 rows created.

SQL> select /*+ FIRST_ROWS */ * from test   2 where rownum < 20
  3 and p > 0;

         P


        15
        25
        35
        45
        55
        65
        75
        85
        95
       105
       115
       125
       135
       145
       155
       165
       175
       185
       195

19 rows selected.

SQL> analyze index test_ix validate structure;

Index analyzed.

SQL> select lf_blks, lf_rows, del_lf_rows   2 from index_stats;

   LF_BLKS LF_ROWS DEL_LF_ROWS
---------- ---------- -----------

        50 49999 0

SQL> delete from test
  2 where mod(trunc((p-5)/10),5) = 0;

9999 rows deleted.

SQL> commit;

Commit complete.

SQL> select /*+ FIRST_ROWS */ * from test   2 where rownum < 20
  3 and p > 0;

         P


        15
        25
        35
        45
        65
        75
        85
        95
       115
       125
       135
       145
       165
       175
       185
       195
       215
       225
       235

19 rows selected.

SQL> analyze index test_ix validate structure;

Index analyzed.

SQL> select lf_blks, lf_rows, del_lf_rows   2 from index_stats;

   LF_BLKS LF_ROWS DEL_LF_ROWS
---------- ---------- -----------

        50 49999 9999

SQL> insert into test
  2 select rownum*50
  3 from sys.source$
  4 where rownum < 10000;

9999 rows created.

SQL> commit;

Commit complete.

SQL> analyze index test_ix validate structure;

Index analyzed.

SQL> select /*+ FIRST_ROWS */ * from test   2 where rownum < 20
  3 and p > 0;

         P


        15
        25
        35
        45
        50
        65
        75
        85
        95
       100
       115
       125
       135
       145
       150
       165
       175
       185
       195

19 rows selected.

SQL> select lf_blks, lf_rows, del_lf_rows   2 from index_stats;

   LF_BLKS LF_ROWS DEL_LF_ROWS
---------- ---------- -----------

        50 49999 0

Bottom Line: I stand by my original premise - statistics alone do not determine an indexes candicacy for rebuild. Some additional knowledge, eg "I know the rows I've deleted will never be replaced" etc is needed.

hth
connor


Connor McDonald
http://www.oracledba.co.uk
http://www.oaktable.net

"Remember amateurs built the ark - Professionals built the Titanic"



Do You Yahoo!?
Everything you'll ever need on one web page from News and Sport to Email and Music Charts http://uk.my.yahoo.com
-- 
Please see the official ORACLE-L FAQ: http://www.orafaq.com
-- 
Author: =?iso-8859-1?q?Connor=20McDonald?=
  INET: hamcdc_at_yahoo.co.uk

Fat City Network Services    -- (858) 538-5051  FAX: (858) 538-5051
San Diego, California        -- Public Internet access / Mailing Lists
--------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
to: ListGuru_at_fatcity.com (note EXACT spelling of 'ListGuru') and in
the message BODY, include a line containing: UNSUB ORACLE-L
(or the name of mailing list you want to be removed from).  You may
also send the HELP command for other information (like subscribing).
Received on Wed Aug 07 2002 - 17:16:39 CDT

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US