You are on page 1of 51

Oracle Performance Tuning

Tamilselvan G
Be
In ac
Co f o t o n
rp ech
or
at
io
n

-5
ss
a
Cl

Beacon infotech Corporation


www.oracleact.com

2007-11-25

Oracle Performance Tuning

Major
Major Types
Types of
of Indexes
Indexes
1.
1.
2.
2.

B*Tree
B*Tree Index
Index itithas
hassubtype
subtype also.
also.
Index
IndexOrganized
Organized Table
Table

3.
3.
4.
4.

Index
IndexCluster
Cluster
Function
FunctionBased
Based Index
Index

5.
5.
6.
6.

Reverse
Reverse Key
KeyIndex
Index
Descending
DescendingIndex
Index

7.
7.
8.
8.

Bit
Bit Map
MapIndex
Index
Application
Application Domain
DomainIndex
Index

9.
9. Intermedia
IntermediaText
Text Index
Index
10.
10.R*Tree
R*TreeIndex
Index
Beacon infotech Corporation
www.oracleact.com

2007-11-25

Oracle Performance Tuning

1. B-Tree Index

Index
IndexBlock
BlockStructure
Structure
Root
Root Block
Block
Branch
BranchBlock
Block
Leaf
Leaf Block
Block
One
One column
columnIndex
Index
Three
Three columns
columnsIndex
Index
Low
LowLevel
LevelProcessing
Processing
Myths
Mythsabout
aboutIndex
Index

Beacon infotech Corporation


www.oracleact.com

2007-11-25

Oracle Performance Tuning

B-Tree Index With Height 4


Root Level 3

Branch Level 2

Branch Level 1

Branch Level 2

Branch Level 1

Branch Level 1

Branch Level 1

Leaf Level 0

Leaf Level 0

Leaf Level 0
Leaf Level 0

Leaf Level 0
Leaf Level 0
Leaf Level 0

Leaf Level 0

Beacon infotech Corporation


www.oracleact.com

2007-11-25

Oracle Performance Tuning

B-Tree Index

SQL> select /*+ full(a) parallel(a,8) */ count(*) from sales a;

Columns Indexed:

COUNT(*)
---------14,336,064

SQL> select index_name, column_name from


user_ind_columns
where index_name = 'SALES_IDX_2' ;
INDEX_NAME
COLUMN_NAME
------------------------------ ----------------SALES_IDX_2
STATE
SALES_IDX_2
SALE_MONTH
SALES_IDX_2
SALE_YEAR
SALES_IDX_2
PROD_ID
SALES_IDX_2
COMM_1

SQL> select table_name, index_name from dba_indexes


where table_name = 'SALES' ;
TABLE_NAME
INDEX_NAME
------------------------------ -----------------------------SALES
SALES_IDX_2

SQL> analyze index sales_idx_2 validate structure ;


SQL> select data_object_id, object_id, object_name
from dba_objects
where object_name ='SALES_IDX_2' ;
DATA_OBJECT_ID OBJECT_ID OBJECT_NAME
----------------------------------68475
68475
SALES_IDX_2

Index analyzed.

SQL> select name, height, blocks, lf_blks, br_blks, DEL_LF_ROWS from index_stats ;

NAME
------------

HEIGHT BLOCKS
---------- ----------

SALES_IDX_2
Beacon infotech Corporation
www.oracleact.com

204800

LF_BLKS BR_BLKS DEL_LF_ROWS


----------------------------150465

1431

2007-11-25

Oracle Performance Tuning

B-Tree Index

SQL>alter session set events


'immediate trace name treedump level 68475' ;
*** 2006-05-22 13:17:48.900
*** SESSION ID:(34.43482) 2006-05-22 13:17:48.886
----- begin tree dump
branch: 0x640fa0a 104921610 (0: nrow: 16, level: 3)
branch: 0x641277d 104933245 (-1: nrow: 107, level: 2)
branch: 0x640fa76 104921718 (-1: nrow: 106, level: 1)
leaf: 0x640fa0b 104921611 (-1: nrow: 95 rrow: 95)
leaf: 0x640fa0c 104921612 (0: nrow: 95 rrow: 95)
leaf: 0x640fa0d 104921613 (1: nrow: 95 rrow: 95)
leaf: 0x640fa0e 104921614 (2: nrow: 95 rrow: 95)
leaf: 0x640fa0f 104921615 (3: nrow: 95 rrow: 95)
(Few lines are deleted )
branch: 0x640fae3 104921827 (0: nrow: 108, level: 1)
leaf: 0x640fa75 104921717 (-1: nrow: 95 rrow: 95)
leaf: 0x640fa77 104921719 (0: nrow: 95 rrow: 95)
leaf: 0x640fa78 104921720 (1: nrow: 95 rrow: 95)
( lines are deleted)
leaf: 0x6414591 104940945 (70: nrow: 95 rrow: 95)
leaf: 0x6414592 104940946 (71: nrow: 77 rrow: 77)
----- end tree dump
Beacon infotech Corporation
www.oracleact.com

Note:
PCTFREE is not used in
branch blocks, hence they
are well packed.
The index height is 4 as you
see the highest level 3.
104921610 is the root block
and has 16 entries.
Root and branch blocks do
not have rrow.
NROW is the number of
slots in the block directory
currently in use.
RROW is the number that
would be in use after all
current transactions have
committed and the block has
been cleaned.
2007-11-25

Oracle Performance Tuning

B-Tree Index

Let use study the root block, 104921610.


To get the file # and block #, use DBMS_UTILITY package.
SQL> begin
2 dbms_output.put_line(
3
dbms_utility.data_block_address_file(dba =>104921610 )
4 );
5 dbms_output.put_line(
6
dbms_utility.data_block_address_block(dba =>104921610 )
7 );
8 end;
9 /
25
------- File #
64010 ------- Block #

Beacon infotech Corporation


www.oracleact.com

2007-11-25

Oracle Performance Tuning

B-Tree Index

SQL> alter system dump datafile 25 block 64010 ;

*** 2006-05-22 13:26:39.747


*** SESSION ID:(34.43484) 2006-05-22 13:26:39.746
Start dump data blocks tsn: 11 file#: 25 minblk 64010 maxblk 64010
buffer tsn: 11 rdba: 0x0640fa0a (25/64010)
scn: 0x0000.066ce790 seq: 0x01 flg: 0x06 tail: 0xe7900601
frmt: 0x02 chkval: 0x7a20 type: 0x06=trans data
Block header dump: 0x0640fa0a
Object id on Block? Y
seg/obj: 0x10b7b csc: 0x00.66ce78f itc: 1 flg: - typ: 2 - INDEX
fsl: 0 fnx: 0x0 ver: 0x01
Itl
Xid
Uba
Flag Lck
Scn/Fsc
0x01 0x0002.016.000091ff 0x00800052.1052.06 --U- 1 fsc 0x0000.066ce790
Branch block dump
=================
Note: The root block has only one ITL.
Rdba Relative data block address
Scn - System change number
Seq - Number of block changes
Seg/obj Object id
Typ Segment type (2 for b*tree index)
Beacon infotech Corporation
www.oracleact.com

ITL Interested Transaction List


Xid Transaction ID
Uba Undo block address
Flag LCk - Flag and Lock Info
Fsc SCN of transaction

2007-11-25

Oracle Performance Tuning

B-Tree Index

Branch block dump ( Logically ROOT BLOCK)


=================
header address 4565966916=0x110272044
kdxcolev 3
----------- Current Index Level
KDXCOLEV Flags = - - kdxcolok 1
--------- indicates brock transaction is happening
kdxcoopc 0x81: opcode=1: iot flags=--- is converted=Y --- internal operation code
kdxconco 6
--- Index column count
kdxcosdc 0
--- count of index structural changes involving block
kdxconro 15
----- Number of entries
kdxcofbo 58=0x3a
--- offset to beginning of free space within a block
kdxcofeo 6947=0x1b23
-- offset to end of free space
kdxcoavs 6889
-- available space in a block
kdxbrlmc 104933245=0x641277d
---- First Branch block at level 2
kdxbrsno 14
--- last index entry to be modified
kdxbrbksz 8056
-------------- Usable Space available for entries
row#0[7981] dba: 109289103=0x6839e8f
------- 2nd branch block at level 2
col 0; len 2; (2): 46 4c
col 1; len 2; (2): c1 03
col 2; len 3; (3): c2 15 02
col 3; len 2; (2): c2 02
col 4; len 50; (50):
78 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
col 5; len 6; (6): 03 80 47 2a 00 10
(few lines are omitted)

Beacon infotech Corporation


www.oracleact.com

2007-11-25

Oracle Performance Tuning

B-Tree Index

Continued from previous page


row#1[7908] dba: 92529418=0x583e30a
col 0; len 2; (2): 46 4c
col 1; len 2; (2): c1 08
col 2; len 3; (3): c2 15 02
col 3; len 2; (2): c2 02
col 4; len 50; (50):
78 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
col 5; len 4; (4): 04 81 23 90
(few lines are omitted)
row#14[6947] dba: 104940948=0x6414594
col 0; len 2; (2): 53 43
col 1; len 2; (2): c1 0b
col 2; len 3; (3): c2 15 03
col 3; len 2; (2): c2 02
col 4; len 50; (50):
78 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
col 5; len 4; (4): 04 81 1c c0
----- end of branch block dump ----End dump data blocks tsn: 11 file#: 25 minblk 64010 maxblk 64010
Beacon infotech Corporation
www.oracleact.com

10

2007-11-25

Oracle Performance Tuning

B-Tree Index

Get the LEVEL 2 only from treedump


$ grep "level: 2" sales_idx_2_treedump.trc
branch: 0x641277d 104933245 (-1: nrow: 107, level: 2)
branch: 0x6839e8f 109289103 (0: nrow: 75, level: 2)
branch: 0x583e30a 92529418 (1: nrow: 106, level: 2)
branch: 0x641e4b3 104981683 (2: nrow: 96, level: 2)
branch: 0x583b16c 92516716 (3: nrow: 107, level: 2)
branch: 0x641a4f5 104965365 (4: nrow: 62, level: 2)
branch: 0x6837f68 109281128 (5: nrow: 107, level: 2)
branch: 0x6c3cb73 113494899 (6: nrow: 63, level: 2)
branch: 0x640f564 104920420 (7: nrow: 107, level: 2)
branch: 0x64238df 105003231 (8: nrow: 57, level: 2)
branch: 0x640c2fb 104907515 (9: nrow: 106, level: 2)
branch: 0x683c79f 109299615 (10: nrow: 55, level: 2)
branch: 0x6409104 104894724 (11: nrow: 106, level: 2)
branch: 0x6420feb 104992747 (12: nrow: 80, level: 2)
branch: 0x6c3b178 113488248 (13: nrow: 107, level: 2)
branch: 0x6414594 104940948 (14: nrow: 73, level: 2)
Beacon infotech Corporation
www.oracleact.com

11

Similarly, you can


get LEVEL 1
information.

2007-11-25

Oracle Performance Tuning

B-Tree Index

Single
Column
Index

Beacon infotech Corporation


www.oracleact.com

12

2007-11-25

Oracle Performance Tuning

B-Tree Index
The tree dump shows:

Let us first build a table and an index


*** 2006-05-20 23:40:27.776
*** SESSION ID:(34.33892) 2006-05-20 23:40:27.775
----- begin tree dump
branch: 0x742260a 121775626 (0: nrow: 8, level: 1)
leaf: 0x742260b 121775627 (-1: nrow: 4 rrow: 4)
leaf: 0x742260c 121775628 (0: nrow: 4 rrow: 4)
leaf: 0x742260d 121775629 (1: nrow: 4 rrow: 4)
leaf: 0x742260e 121775630 (2: nrow: 4 rrow: 4)
leaf: 0x742260f 121775631 (3: nrow: 4 rrow: 4)
leaf: 0x7422610 121775632 (4: nrow: 4 rrow: 4)
leaf: 0x7422611 121775633 (5: nrow: 4 rrow: 4)
leaf: 0x7422612 121775634 (6: nrow: 2 rrow: 2)
----- end tree dump

create table my_table2


as
select rownum + 30000 id,
rpad('x',150,'x') some
from dba_objects where rownum <= 30 ;

create index my_table2_idx on my_table2


( id)
pctfree 99;

Note:
To get multiple leaf blocks, I used PCTFREE 99.
Since the number of entries are only 30, there is no
branch blocks.

Beacon infotech Corporation


www.oracleact.com

13

2007-11-25

Oracle Performance Tuning

B-Tree Index

Branch (in this case root) block dump

*** 2006-05-20 23:42:51.375


*** SESSION ID:(34.33895) 2006-05-20 23:42:51.374
Start dump data blocks tsn: 10 file#: 29 minblk 140810 maxblk
140810
buffer tsn: 10 rdba: 0x0742260a (29/140810)
scn: 0x0000.06762c36 seq: 0x01 flg: 0x00 tail: 0x2c360601
frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
Block header dump: 0x0742260a
Object id on Block? Y
seg/obj: 0x10b96 csc: 0x00.6762c34 itc: 1 flg: - typ: 2 - INDEX
fsl: 0 fnx: 0x0 ver: 0x01

Itl
Xid
Uba
Flag Lck
Scn/Fsc
0x01 0xffff.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.06762c34

Branch block dump


=================
header address
4565966916=0x110272044
kdxcolev 1
KDXCOLEV Flags = - - kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 7
kdxcofbo 42=0x2a
kdxcofeo 7986=0x1f32
kdxcoavs 7944
kdxbrlmc 121775627=0x742260b
kdxbrsno 0
kdxbrbksz 8056

--- continued --

Where 121775627 is the first leaf block.

Key Value is NOT stored for the first block in the branch.
Beacon infotech Corporation
www.oracleact.com

14

2007-11-25

Oracle Performance Tuning

B-Tree Index

Branch (in this case root) block dump


row#0[8046] dba: 121775628=0x742260c 2nd leaf block
col 0; len 4; (4): c3 04 01 06 --- Only Index key value is stored
col 1; TERM
row#1[8036] dba: 121775629=0x742260d
col 0; len 4; (4): c3 04 01 0a
col 1; TERM
row#2[8026] dba: 121775630=0x742260e
col 0; len 4; (4): c3 04 01 0e
col 1; TERM
row#3[8016] dba: 121775631=0x742260f
col 0; len 4; (4): c3 04 01 12
col 1; TERM
row#4[8006] dba: 121775632=0x7422610
col 0; len 4; (4): c3 04 01 16
col 1; TERM
row#5[7996] dba: 121775633=0x7422611
col 0; len 4; (4): c3 04 01 1a
col 1; TERM
row#6[7986] dba: 121775634=0x7422612
col 0; len 4; (4): c3 04 01 1e
col 1; TERM
----- end of branch block dump ----End dump data blocks tsn: 10 file#: 29 minblk 140810 maxblk 140810

Beacon infotech Corporation


www.oracleact.com

15

SQL> select id, dump(id, 16)


from my_table2 ;

ID DUMP(ID,16)
------ -----------------------------30001 Typ=2 Len=4: c3,4,1,2
30002 Typ=2 Len=4: c3,4,1,3
30003 Typ=2 Len=4: c3,4,1,4
30004 Typ=2 Len=4: c3,4,1,5
30005 Typ=2 Len=4: c3,4,1,6
30006 Typ=2 Len=4: c3,4,1,7
30007 Typ=2 Len=4: c3,4,1,8
30008 Typ=2 Len=4: c3,4,1,9
30009 Typ=2 Len=4: c3,4,1,a
30010 Typ=2 Len=4: c3,4,1,b
30011 Typ=2 Len=4: c3,4,1,c
30012 Typ=2 Len=4: c3,4,1,d
30013 Typ=2 Len=4: c3,4,1,e
30014 Typ=2 Len=4: c3,4,1,f
30015 Typ=2 Len=4: c3,4,1,10
-------------30029 Typ=2 Len=4: c3,4,1,1e
30030 Typ=2 Len=4: c3,4,1,1f
30 rows selected.

2007-11-25

Oracle Performance Tuning

B-Tree Index

Let us study one of the leaf block, 121775628 :


*** 2006-05-20 23:49:17.760
*** SESSION ID:(34.33911) 2006-05-20 23:49:17.740
Start dump data blocks tsn: 10 file#: 29 minblk 140812 maxblk 140812
buffer tsn: 10 rdba: 0x0742260c (29/140812)
scn: 0x0000.06762c35 seq: 0x02 flg: 0x04 tail: 0x2c350602
frmt: 0x02 chkval: 0xd2d4 type: 0x06=trans data
Block header dump: 0x0742260c
Object id on Block? Y
seg/obj: 0x10b96 csc: 0x00.6762c34 itc: 2 flg: - typ: 2 - INDEX
fsl: 0 fnx: 0x0 ver: 0x01

Itl
Xid
Uba
Flag Lck
Scn/Fsc
0x01 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
0x02 0xffff.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.06762c34

By default 2 ITL slots (INITRAN 2) are created in the leaf block.

Beacon infotech Corporation


www.oracleact.com

16

2007-11-25

Oracle Performance Tuning

B-Tree Index

leaf block, 121775628 continued .


Leaf block dump
===============
header address 4565966940=0x11027205c
kdxcolev 0
KDXCOLEV Flags = - - kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 4
kdxcofbo 44=0x2c
kdxcofeo 7976=0x1f28
kdxcoavs 7932
kdxlespl 0
kdxlende 0
kdxlenxt 121775629=0x742260d
-------- Pointer to previous block
kdxleprv 121775627=0x742260b
-------- Pointer to Next Block
kdxledsz 0
kdxlebksz 8032

Branch blocks do not


participate in the range scan
because of the pointers
stored in the leaf blocks

Beacon infotech Corporation


www.oracleact.com

17

2007-11-25

Oracle Performance Tuning

B-Tree Index

leaf block, 121775628 continued .


row#0[8018] flag: -----, lock: 0
col 0; len 4; (4): c3 04 01 06
col 1; len 6; (6): 04 83 b6 0a 00 04 --- ROWID
row#1[8004] flag: -----, lock: 0
col 0; len 4; (4): c3 04 01 07
col 1; len 6; (6): 04 83 b6 0a 00 05
row#2[7990] flag: -----, lock: 0
col 0; len 4; (4): c3 04 01 08
col 1; len 6; (6): 04 83 b6 0a 00 06
row#3[7976] flag: -----, lock: 0
col 0; len 4; (4): c3 04 01 09
col 1; len 6; (6): 04 83 b6 0a 00 07
----- end of leaf block dump ----End dump data blocks tsn: 10 file#: 29 minblk 140812 maxblk 140812

Oracle still uses


restricted ROWID
in the index.

SQL> select id, dump(id,16) , dump(rowid,16) from my_table2


where id = 30005

ID DUMP(ID,16)
DUMP(ROWID,16)
------ ------------------------------ ---------------------------------------30005 Typ=2 Len=4: c3,4,1,6
Typ=69 Len=10: 0,1,b,94,4,83,b6,a,0,4

Beacon infotech Corporation


www.oracleact.com

18

2007-11-25

Oracle Performance Tuning

B-Tree Index

Three
Column
Index

Beacon infotech Corporation


www.oracleact.com

19

2007-11-25

Oracle Performance Tuning

B-Tree Index

Let us first build a table and an index

Tree dump for the index:


create table my_table (id number(5), name varchar2(10),
some_txt varchar2(150)) ;

insert into my_table values (15001, 'TAMIL', rpad('x',150,'x'));


insert into my_table values (15002, 'SCOTT', rpad('x',150,'x'));
insert into my_table values (15003, 'TANDON', rpad('x',150,'x'));
insert into my_table values (15004, 'KUMAR', rpad('x',150,'x'));
insert into my_table values (15005, 'PALANI', rpad('x',150,'x'));
insert into my_table values (15006, 'SIVA', rpad('x',150,'x'));
insert into my_table values (15007, 'SUDA', rpad('x',150,'x'));
insert into my_table values (15008, 'APPULLY', rpad('x',150,'x'));
insert into my_table values (15009, 'MANOJ', rpad('x',150,'x'));
insert into my_table values (15010, 'MIKE', rpad('x',150,'x'));

----- begin tree dump


branch: 0x483840a 75727882 (0: nrow: 4, level: 1)
leaf: 0x483840b 75727883 (-1: nrow: 3 rrow: 3)
leaf: 0x483840c 75727884 (0: nrow: 3 rrow: 3)
leaf: 0x483840d 75727885 (1: nrow: 3 rrow: 3)
leaf: 0x483840e 75727886 (2: nrow: 1 rrow: 1)
----- end tree dump

commit;

create index my_table_idx on my_table ( name, id, some_txt)


pctfree 90;

Beacon infotech Corporation


www.oracleact.com

20

2007-11-25

Oracle Performance Tuning

B-Tree Index

Branch block, 75727882 details are given below:


*** 2006-05-20 23:21:17.952
*** SESSION ID:(34.33844) 2006-05-20 23:21:17.951
Start dump data blocks tsn: 10 file#: 18 minblk 230410 maxblk 230410
buffer tsn: 10 rdba: 0x0483840a (18/230410)
scn: 0x0000.067620be seq: 0x01 flg: 0x00 tail: 0x20be0601
frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
Block header dump: 0x0483840a
Object id on Block? Y
seg/obj: 0x10b93 csc: 0x00.67620bd itc: 1 flg: - typ: 2 - INDEX
fsl: 0 fnx: 0x0 ver: 0x01

Itl

Xid

Uba

Flag Lck

0x01 0xffff.000.00000000 0x00000000.0000.00 C---

Beacon infotech Corporation


www.oracleact.com

Scn/Fsc
0 scn 0x0000.067620bd

21

Branch block dump


=================
header address
4565966916=0x110272044
kdxcolev 1
KDXCOLEV Flags = - - kdxcolok 0
kdxcoopc 0x80: opcode=0: iot
flags=--- is converted=Y
kdxconco 4
kdxcosdc 0
kdxconro 3
kdxcofbo 34=0x22
kdxcofeo 8031=0x1f5f
kdxcoavs 7997
kdxbrlmc 75727883=0x483840b
kdxbrsno 0
kdxbrbksz 8056

2007-11-25

Oracle Performance Tuning

B-Tree Index

Branch block, 75727882 details are given below:


row#0[8048] dba: 75727884=0x483840c
col 0; len 2; (2): 4d 49
col 1; TERM
row#1[8040] dba: 75727885=0x483840d
col 0; len 2; (2): 53 49
col 1; TERM
row#2[8031] dba: 75727886=0x483840e
col 0; len 3; (3): 54 41 4e
col 1; TERM
----- end of branch block dump ----End dump data blocks tsn: 10 file#: 18 minblk 230410 maxblk 230410

Note: Watch out TERM in the branch data. Available space was 7997.
Roughly, 480 bytes (3 * 160) is needed for 3 entries in the branch block.
My assumption is: Oracle either compress all the key values or use
some hash value to store it in the col 1.

Beacon infotech Corporation


www.oracleact.com

22

2007-11-25

Oracle Performance Tuning

B-Tree Index

Branch block, 75727882 details are given below:


SQL>select id, name, dump(id,16), dump(name,16) from my_table ;

ID NAME
---------- ---------15001 TAMIL
15002 SCOTT
15003 TANDON
15004 KUMAR
15005 PALANI
15006 SIVA
15007 SUDA
15008 APPULLY
15009 MANOJ
15010 MIKE

DUMP(ID,16)
DUMP(NAME,16)
-----------------------------------------------------Typ=2 Len=4: c3,2,33,2 Typ=1 Len=5: 54,41,4d,49,4c
Typ=2 Len=4: c3,2,33,3 Typ=1 Len=5: 53,43,4f,54,54
Typ=2 Len=4: c3,2,33,4 Typ=1 Len=6: 54,41,4e,44,4f,4e
Typ=2 Len=4: c3,2,33,5 Typ=1 Len=5: 4b,55,4d,41,52
Typ=2 Len=4: c3,2,33,6 Typ=1 Len=6: 50,41,4c,41,4e,49
Typ=2 Len=4: c3,2,33,7 Typ=1 Len=4: 53,49,56,41
Typ=2 Len=4: c3,2,33,8 Typ=1 Len=4: 53,55,44,41
Typ=2 Len=4: c3,2,33,9 Typ=1 Len=7: 41,50,50,55,4c,4c,59
Typ=2 Len=4: c3,2,33,a Typ=1 Len=5: 4d,41,4e,4f,4a
Typ=2 Len=4: c3,2,33,b Typ=1 Len=4: 4d,49,4b,45

10 rows selected.

Beacon infotech Corporation


www.oracleact.com

23

2007-11-25

Oracle Performance Tuning

B-Tree Index

Leaf block, 75727884 details are given below:

*** SESSION ID:(34.33829) 2006-05-20 23:08:06.927


Start dump data blocks tsn: 10 file#: 18 minblk 230412 maxblk
230412
buffer tsn: 10 rdba: 0x0483840c (18/230412)
scn: 0x0000.067620be seq: 0x02 flg: 0x04 tail: 0x20be0602
frmt: 0x02 chkval: 0xf11d type: 0x06=trans data
Block header dump: 0x0483840c
Object id on Block? Y
seg/obj: 0x10b93 csc: 0x00.67620bd itc: 2 flg: - typ: 2 INDEX
fsl: 0 fnx: 0x0 ver: 0x01

Itl
Xid
Uba
Flag Lck
Scn/Fsc
0x01 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
0x02 0xffff.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.067620bd

Beacon infotech Corporation


www.oracleact.com

24

Leaf block dump


===============
header address
4565966940=0x11027205c
kdxcolev 0
KDXCOLEV Flags = - - kdxcolok 0
kdxcoopc 0x80: opcode=0: iot
flags=--- is converted=Y
kdxconco 4
kdxcosdc 0
kdxconro 3
kdxcofbo 42=0x2a
kdxcofeo 7516=0x1d5c
kdxcoavs 7474
kdxlespl 0
kdxlende 0
kdxlenxt 75727885=0x483840d
kdxleprv 75727883=0x483840b
kdxledsz 0
kdxlebksz 8032

2007-11-25

Oracle Performance Tuning

B-Tree Index

Leaf block, 75727884 details are given below:


row#0[7861] flag: -----, lock: 0
col 0; len 4; (4): 4d 49 4b 45
col 1; len 4; (4): c3 02 33 0b
col 2; len 150; (150):

--- MIKE
--- 15010

78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78
78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78
78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78
78 78 78 78 78 78 78 78
78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78

col 3; len 6; (6): 07 c0 32 0a 00 09


row#1[7688] flag: -----, lock: 0
col 0; len 6; (6): 50 41 4c 41 4e 49
col 1; len 4; (4): c3 02 33 06
col 2; len 150; (150):
78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78
78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78
78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78
78 78 78 78 78 78 78 78
78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78

col 3; len 6; (6): 07 c0 32 0a 00 04


row#2[7516] flag: -----, lock: 0
col 0; len 5; (5): 53 43 4f 54 54 --- SCOTT
col 1; len 4; (4): c3 02 33 03
--- 15002
col 2; len 150; (150):
78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78
78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78
78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78
78 78 78 78 78 78 78 78
78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78

col 3; len 6; (6): 07 c0 32 0a 00 01


----- end of leaf block dump ----End dump data blocks tsn: 10 file#: 18 minblk 230412 maxblk 230412
Beacon infotech Corporation
www.oracleact.com

25

2007-11-25

Oracle Performance Tuning

B-Tree Index

Low Level
Processing

Beacon infotech Corporation


www.oracleact.com

26

2007-11-25

Oracle Performance Tuning

B-Tree Index

A. Inserting New Entry in a Leaf Block


When Free Space is Available
SQL> select object_id,
object_name from user_objects
where object_name in
('MY_TABLE',
'MY_TABLE_IDX');

create table my_table


(id number(5),
name varchar2(10),
some_txt varchar2(150)) ;

insert into my_table values (15001, 'A_TAMIL', rpad('x',150,'x'));


OBJECT_ID OBJECT_NAME
insert into my_table values (15002, 'A_SCOTT', rpad('x',150,'x'));
---------- ------------insert into my_table values (15003, 'A_TANDON', rpad('x',150,'x'));
68504 MY_TABLE_IDX
insert into my_table values (15004, 'B_KUMAR', rpad('x',150,'x'));
68503 MY_TABLE
insert into my_table values (15005, 'B_PALANI', rpad('x',150,'x'));
insert into my_table values (15006, 'B_SIVA', rpad('x',150,'x'));
insert into my_table values (15010, 'D_MIKE', rpad('x',150,'x'));
commit;
create index my_table_idx on my_table
( name, id, some_txt)
pctfree 90;

Beacon infotech Corporation


www.oracleact.com

27

2007-11-25

Oracle Performance Tuning

B-Tree Index

Get a treedump

SQL> alter system set events 'immediate trace name


treedump level 68504';
*** 2006-05-22 20:36:11.414
*** SESSION ID:(34.45136) 2006-05-22 20:36:11.391
----- begin tree dump
branch: 0x483840a 75727882 (0: nrow: 3, level: 1)
leaf: 0x483840b 75727883 (-1: nrow: 3 rrow: 3) -- for Name starting A_XXXX
leaf: 0x483840c 75727884 (0: nrow: 3 rrow: 3) -- for Name starting B_XXXX
leaf: 0x483840d 75727885 (1: nrow: 1 rrow: 1) -- for Name starting D_XXXX
----- end tree dump

Now I am going to insert one row and let see what happens in the index leaf
blocks.

Beacon infotech Corporation


www.oracleact.com

28

2007-11-25

Oracle Performance Tuning

B-Tree Index

SQL> insert into my_table values (15007, 'B_RAJA', rpad('x',150,'x'));


SQK> Commit;

SQL> alter system set events 'immediate trace name treedump level 68504';
*** SESSION ID:(34.45141) 2006-05-22 20:42:43.420
----- begin tree dump
branch: 0x483840a 75727882 (0: nrow: 3, level: 1)
leaf: 0x483840b 75727883 (-1: nrow: 3 rrow: 3)
leaf: 0x483840c 75727884 (0: nrow: 4 rrow: 4) --- From 3 it went to 4
leaf: 0x483840d 75727885 (1: nrow: 1 rrow: 1)
----- end tree dump

Since the new key value start with B_xxxx, it went to the block, 75727884.
All the leaf blocks have lot of free space because I used PCTFREE 90.

Beacon infotech Corporation


www.oracleact.com

29

2007-11-25

Oracle Performance Tuning

B-Tree Index

Now I am going to insert one row with NAME starting with C_XXXX and lets
see what happens in the index leaf blocks.
SQL> insert into my_table values (15008, 'C_KANNAN', rpad('x',150,'x')) ;
SQL> commit;

SQL> alter system set events 'immediate trace name treedump level 68504';
*** 2006-05-22 20:47:46.475
*** SESSION ID:(34.45144) 2006-05-22 20:47:46.474
----- begin tree dump
branch: 0x483840a 75727882 (0: nrow: 3, level: 1)
leaf: 0x483840b 75727883 (-1: nrow: 3 rrow: 3)
leaf: 0x483840c 75727884 (0: nrow: 5 rrow: 5)
leaf: 0x483840d 75727885 (1: nrow: 1 rrow: 1)
----- end tree dump

--- the block has now 5 rows.

Note: Before inserting a new entry in a leaf block, Oracle has to find out the
highest block just lower than the incoming value.
This is one of reasons why FREELIST parameter should not be set more than 1
for indexes.
Beacon infotech Corporation
www.oracleact.com

30

2007-11-25

Oracle Performance Tuning

B-Tree Index

B. A. Inserting New Entry in a Leaf Block


When Free Space is NOT Available
create table my_table (id number(5), name varchar2(10),
some_txt varchar2(2500)) ;

insert into my_table values (50001, 'A_TAMIL', rpad('x',2500,'x'));


insert into my_table values (50002, 'A_SCOTT', rpad('x',2500,'x'));
insert into my_table values (50003, 'A_TANDON', rpad('x',2500,'x'));
insert into my_table values (50004, 'B_KUMAR', rpad('x',2500,'x'));
insert into my_table values (50005, 'B_PALANI', rpad('x',2500,'x'));
insert into my_table values (50006, 'B_SIVA', rpad('x',2500,'x'));
insert into my_table values (50010, 'D_MIKE', rpad('x',2500,'x'));
commit;

select object_id,
object_name
from user_objects
where object_name in
('MY_TABLE',
'MY_TABLE_IDX');

OBJECT_ID OBJECT_NAME
-----------------------68510
MY_TABLE_IDX
68509
MY_TABLE

create index my_table_idx on my_table


( name, id, some_txt)
pctfree 5;

SQL> alter system set events 'immediate trace name treedump level 68510' ;

System altered.

Beacon infotech Corporation


www.oracleact.com

31

2007-11-25

Oracle Performance Tuning

B-Tree Index

B. INSERTING NEW ENTRY IN A LEAF BLOCK


WHEN FREE SPACE IS NOT AVAILABLE
Treedump

*** 2006-05-22 21:09:04.691


*** SESSION ID:(34.45223) 2006-05-22 21:09:04.690
----- begin tree dump
branch: 0x483840a 75727882 (0: nrow: 3, level: 1)
leaf: 0x483840b 75727883 (-1: nrow: 3 rrow: 3)
leaf: 0x483840c 75727884 (0: nrow: 3 rrow: 3)
leaf: 0x483840d 75727885 (1: nrow: 1 rrow: 1)
----- end tree dump

Now I insert a row that has a name starting with C_XXXX and
let us see what happens to the index leaf blocks.
SQL> insert into my_table values (50007, 'C_SUBBU', rpad('x',2500,'x'));
1 row created.
SQL> commit;
Commit complete.
Beacon infotech Corporation
www.oracleact.com

32

2007-11-25

Oracle Performance Tuning

B-Tree Index

B. INSERTING NEW ENTRY IN A LEAF BLOCK


WHEN FREE SPACE IS NOT AVAILABLE
SQL> alter system set events 'immediate trace name treedump level 68510' ;
*** 2006-05-22 21:14:21.568
*** SESSION ID:(34.45226) 2006-05-22 21:14:21.567
----- begin tree dump
branch: 0x483840a 75727882 (0: nrow: 4, level: 1)
leaf: 0x483840b 75727883 (-1: nrow: 3 rrow: 3)
leaf: 0x483840c 75727884 (0: nrow: 3 rrow: 3)
leaf: 0x483840e 75727886 (1: nrow: 1 rrow: 1) ---- NEW BLOCK ADDED
leaf: 0x483840d 75727885 (2: nrow: 1 rrow: 1)
----- end tree dump

Even though the block 75727885 has only one row (for Name D_MIKE),
Oracle will not use that block for the new entry (NAME C_SUBBU) because it
always try to find the highest block just lower than the incoming value. Hence,
finally Oracle added a new block 75727886 for C_SUBBU.

Beacon infotech Corporation


www.oracleact.com

33

2007-11-25

Oracle Performance Tuning

B-Tree Index

Low Level
Split
Processing

Beacon infotech Corporation


www.oracleact.com

34

2007-11-25

Oracle Performance Tuning

B-Tree Index

C. 50:50 Split OR 90:10 Split or 99:1 Split.


SQL> select id, name from my_table;
ID NAME
---------- ---------50001 A_TAMIL
50002 A_SCOTT
50003 A_TANDON
50004 B_KUMAR
50005 B_PALANI
50006 B_SIVA
50010 D_MIKE
50007 C_SUBBU

SQL> select object_id,


object_name from
user_objects where
object_name in
('MY_TABLE',
'MY_TABLE_IDX') ;

OBJECT_ID OBJECT_NAME
---------- ---------------68510 MY_TABLE_IDX
68509 MY_TABLE

8 rows selected.

Inserting highest value in the first leaf block.


SQL> insert into my_table values (50051, 'A_ZORNO', rpad('x',2500,'x'));
1 row created.

SQL> commit;
Commit complete.

Beacon infotech Corporation


www.oracleact.com

35

2007-11-25

Oracle Performance Tuning

B-Tree Index

C. 50:50 Split OR 90:10 Split or 99:1 Split.


SQL> alter system set events 'immediate trace name treedump level 68510';

TREEDUMP

*** 2006-05-22 22:27:39.089


*** SESSION ID:(34.45529) 2006-05-22 22:27:39.087
----- begin tree dump
branch: 0x483840a 75727882 (0: nrow: 5, level: 1)
leaf: 0x483840b 75727883 (-1: nrow: 3 rrow: 3) --- Original Block Not changed
leaf: 0x483840f 75727887 (0: nrow: 1 rrow: 1) ---- New Block for A_ZORNO
leaf: 0x483840c 75727884 (1: nrow: 3 rrow: 3)
leaf: 0x483840e 75727886 (2: nrow: 1 rrow: 1)
leaf: 0x483840d 75727885 (3: nrow: 1 rrow: 1)
----- end tree dump

In this case it is 99:1 Split (Shall we call 90:10 Split ?)


Beacon infotech Corporation
www.oracleact.com

36

2007-11-25

Oracle Performance Tuning

B-Tree Index

C. 50:50 Split OR 90:10 Split or 99:1 Split.


Inserting lowest value.
SQL> insert into my_table values (50052, 'A_BABU', rpad('x', 2500,'x')) ;
1 row created.

SQL> commit;
Commit complete.

TREEDUMP
*** 2006-05-22 22:34:41.973
*** SESSION ID:(34.45531) 2006-05-22 22:34:41.972
----- begin tree dump
branch: 0x483840a 75727882 (0: nrow: 6, level: 1)
leaf: 0x483840b 75727883 (-1: nrow: 2 rrow: 2) -- Original row
leaf: 0x4838410 75727888 (0: nrow: 2 rrow: 2) --- New Block added
leaf: 0x483840f 75727887 (1: nrow: 1 rrow: 1)
leaf: 0x483840c 75727884 (2: nrow: 3 rrow: 3)
leaf: 0x483840e 75727886 (3: nrow: 1 rrow: 1)
leaf: 0x483840d 75727885 (4: nrow: 1 rrow: 1)
----- end tree dump
Beacon infotech Corporation
www.oracleact.com

37

When lowest
value is
inserted,
Oracle splits
the entries in
the block into
50:50.
2007-11-25

Oracle Performance Tuning

B-Tree Index

C. 50:50 Split OR 90:10 Split or 99:1 Split.


SQL> select object_id,
object_name from user_objects
where object_name in
('MY_TABLE',
'MY_TABLE_IDX') ;

I recreated the table.


SQL> select id, name from my_table;

ID NAME
---------- ---------50001 A_ANBU
50002 A_SCOTT
50003 A_TANDON
50004 B_KUMAR
50005 B_PALANI
50006 B_SIVA
50010 D_MIKE

OBJECT_ID OBJECT_NAME
---------- --------------68514 MY_TABLE_IDX
68513 MY_TABLE

7 rows selected.

SQL> alter system set events 'immediate trace name


treedump level 68514 ';

Beacon infotech Corporation


www.oracleact.com

38

2007-11-25

Oracle Performance Tuning

B-Tree Index

C. 50:50 Split OR 90:10 Split or 99:1 Split.


Original Treedump:
*** 2006-05-22 22:44:39.085
*** SESSION ID:(34.45564) 2006-05-22 22:44:39.083
----- begin tree dump
branch: 0x483840a 75727882 (0: nrow: 3, level: 1)
leaf: 0x483840b 75727883 (-1: nrow: 3 rrow: 3)
leaf: 0x483840c 75727884 (0: nrow: 3 rrow: 3)
leaf: 0x483840d 75727885 (1: nrow: 1 rrow: 1)
----- end tree dump

Inserted a row after A_BABU.


SQL> insert into my_table values (50051, 'A_EDWARD', rpad('x',2500,'x'));
1 row created.

SQL> commit;
Commit complete.
Beacon infotech Corporation
www.oracleact.com

39

2007-11-25

Oracle Performance Tuning

B-Tree Index

C. 50:50 Split OR 90:10 Split or 99:1 Split.


New Treedump:
*** 2006-05-22 22:48:27.509
*** SESSION ID:(34.45570) 2006-05-22 22:48:27.508
----- begin tree dump
branch: 0x483840a 75727882 (0: nrow: 4, level: 1)
leaf: 0x483840b 75727883 (-1: nrow: 3 rrow: 3)
leaf: 0x483840e 75727886 (0: nrow: 1 rrow: 1) --------- New block added
leaf: 0x483840c 75727884 (1: nrow: 3 rrow: 3)
leaf: 0x483840d 75727885 (2: nrow: 1 rrow: 1)
----- end tree dump

90:10 or
99:1 Split
happened
when a
middle
value is
inserted.

Lets see what is in the new block.

Beacon infotech Corporation


www.oracleact.com

40

2007-11-25

Oracle Performance Tuning

B-Tree Index

C. 50:50 Split OR 90:10 Split or 99:1 Split.


SQL> begin
2 dbms_output.put_line(
3
dbms_utility.data_block_address_file(dba=>75727886)
4 );
5 dbms_output.put_line(
6
dbms_utility.data_block_address_block(dba=>75727886)
7 );
8 end;
9 /
18
--- File #
230414 --- Block #
Get the block dump
SQL> alter system dump datafile 18 block 230414 ;
System altered.

Beacon infotech Corporation


www.oracleact.com

41

2007-11-25

Oracle Performance Tuning

B-Tree Index

C. 50:50 Split OR 90:10 Split or 99:1 Split.


+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59

kdxlenxt 75727884=0x483840c
Partial dump
kdxleprv 75727883=0x483840b
kdxledsz 0
kdxlebksz 8032
row#0[5507] flag: -----, lock: 0
col 0; len 8; (8): 41 5f 54 41 4e 44 4f 4e -- A_TANDON
col 1; len 4; (4): c3 06 01 04
col 2; len 2500; (2500):
78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78
78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78
(a lot of rows are deleted for readability)
78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78
col 3; len 6; (6): 07 c0 32 0b 00 00
----- end of leaf block dump ----End dump data blocks tsn: 10 file#: 18 minblk 230414 maxblk 230414

When a middle value is inserted and there is NO free space


in the block, then Oracle splits the block into 90:10 (99:1).
Beacon infotech Corporation
www.oracleact.com

42

2007-11-25

Oracle Performance Tuning

B-Tree Index

D. Does the arrival of rows matter


leaf blocks?
The answer is YES.
create table my_table
(id1 number(6),
name varchar2(10),
id2 number(6) );

create index my_table_idx_1 on


my_table (id1) pctfree 10;

create index my_table_idx_2 on


my_table (id2) pctfree 10;

declare
M number ;
N Number := 200001;
begin
For M in 100001 .. 200000 LOOP
N := N - 1;
insert into my_table (id1,name, id2)
values
(M, 'XXXXXX', N);
commit;
END LOOP;
end;
/
spool off

Note: M is increasing and N is


a decreasing.

SQL> select min(id1), max(id1), min(id2), max(id2) from my_table;


MIN(ID1) MAX(ID1) MIN(ID2) MAX(ID2)
---------100001
Beacon infotech Corporation
www.oracleact.com

----------

----------

200000

100001

---------200000

43

2007-11-25

Oracle Performance Tuning

B-Tree Index

SQL> select count(*) from my_table;

Note:
COUNT(*)
---------100000
SQL> analyze index my_table_idx_1 validate structure;
Index analyzed.
SQL> select name, blocks, lf_blks, br_blks, distinct_keys from index_stats;
NAME
-------------MY_TABLE_IDX_1

BLOCKS LF_BLKS BR_BLKS DISTINCT_KEYS


---------------------------------------12800
394
1
100000

SQL> analyze index my_table_idx_2 validate structure;


Index analyzed.

394 leaf
blocks for
the
ascending
sequence vs
406 leaf
blocks for
the
descending
seq. The
difference is
not much.

SQL> select name, blocks, lf_blks, br_blks, distinct_keys from index_stats;


NAME
-------------MY_TABLE_IDX_2
Beacon infotech Corporation
www.oracleact.com

BLOCKS
---------12800

LF_BLKS BR_BLKS DISTINCT_KEYS


------------------------------406
1
100000

44

2007-11-25

Oracle Performance Tuning

B-Tree Index
declare
M number ;
N Number := 200001;
begin
For M in 100001 .. 300000 LOOP
N := N - 1;
insert into my_table (id1,name, id2)
values
(M, 'XXXXXX', N);
commit;
END LOOP;
end;
/
spool off

E. Deleted space is not reused?

This is a myth.
create table my_table
(id1 number(6),
name varchar2(10),
id2 number(6) );

create index my_table_idx_1 on


my_table (id1) pctfree 10;

SQL> analyze index my_table_idx_1


validate structure ;
SQL> select name, blocks, lf_blks, br_blks, distinct_keys from index_stats;
NAME

BLOCKS

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

----------

MY_TABLE_IDX_1

12800

Beacon infotech Corporation


www.oracleact.com

LF_BLKS

BR_BLKS

DISTINCT_KEYS

----------

----------

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

400

45

200000

2007-11-25

Oracle Performance Tuning

B-Tree Index

E. Deleted space is not reused?


Now I delete 50 % of the rows.
SQL> delete my_table where id1 <= 200000 ;
100,000 rows deleted.
SQL> commit;
Commit complete.
SQL> analyze index my_table_idx_1 validate structure ;
Index analyzed.
SQL> select name, blocks, lf_blks, br_blks, del_lf_rows from index_stats;
NAME
BLOCKS LF_BLKS BR_BLKS DEL_LF_ROWS
------------------------------ -------------------------------------MY_TABLE_IDX_1
12800
400
1
86500
I insert 100,000 rows but with different values for ID1
SQL> declare
M number ;
N Number := 200001;
begin
For M in 300001 .. 400000 LOOP
N := N - 1;
insert into my_table (id1,name, id2)
END LOOP;
commit;
end;
/
Beacon infotech Corporation
www.oracleact.com

values

(M, 'XXXXXX', N);

46

2007-11-25

Oracle Performance Tuning

B-Tree Index

E. Deleted space is not reused?


SQL> analyze index my_table_idx_1 validate structure ;
Index analyzed.

SQL> select name, blocks, lf_blks, br_blks, del_lf_rows , distinct_keys, pct_used


from index_stats;

NAME
-------------MY_TABLE_IDX_1

BLOCKS
---------12800

LF_BLKS
---------404

BR_BLKS DEL_LF_ ROWS DISTINCT_KEYS


-------------------------------1
1000
201000

PCT_USED
---------100

You see the number of leaf blocks did not increase by 50%. All the
available free leaf blocks are reused.
PCT_USED column in INDEX_STATS does not tell you the truth
because it assumes that the blocks which are in the FREELIST are
also used by leaf blocks. Hence, we got 100 % PCT_USED.
Beacon infotech Corporation
www.oracleact.com

47

2007-11-25

Oracle Performance Tuning

B-Tree Index

F. Most distinct column should be the first column in


a composite index.
This is another myth.
There is not truth in it. If the optimizer computes low
cost for an indexed access path, it would use it.
The following example will disprove the myth.
create table my_table as
select mod(rownum,5) id1, -- 5 distinct values
mod(rownum,50) id2, -- 50 distinct values
rownum id3,
--- very high distinct values
rpad('x',300,'x') sometxt
from dba_objects;
create index my_table_idx_low on my_table(id1, id2, id3) ;

analyze table my_table compute statistics


for table for all indexes for all indexed columns size 1;

Beacon infotech Corporation


www.oracleact.com

48

SQL> select
distinct id1
from my_table;

ID1
---------0
1
2
3
4

2007-11-25

Oracle Performance Tuning

B-Tree Index

F. Most distinct column should be the first column in a composite


index.
SQL> select * from my_table where id1= 2 and id2 = 29 and id3 = 100 ;
Execution Plan
---------------------------------------------------------0
SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=160)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'MY_TABLE' (Cost=2 Card=1 Bytes=160)
2 1 INDEX (RANGE SCAN) OF 'MY_TABLE_IDX_LOW' (NON-UNIQUE) (Cost=1 Card=1)

As you see the LOW cardinality index is being used.


Another example:
SQL> select * from my_table where id2 = 10 and id3 between 200 and 300 ;
Execution Plan
---------------------------------------------------------0
SELECT STATEMENT Optimizer=CHOOSE (Cost=12 Card=2 Bytes=320)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'MY_TABLE' (Cost=12 Card=2 Bytes=320)
2 1 INDEX (SKIP SCAN) OF 'MY_TABLE_IDX_LOW' (NON-UNIQUE) (Cost=6 Card=2)

I could re-state the statement as:


Use a column in a composite index as a leading column if most of the
queries have predicates of that column.
Beacon infotech Corporation
www.oracleact.com

49

2007-11-25

Oracle Performance Tuning

B-Tree Index

Why is NOT my index being used by the Optimizer?


There are several reasons for an index not being used by the Optimizer.
Some of them are:
1.

Wrong Index Hint

2.

Column is NULL in the WHERE Clause

3.

Table and Indexes are not analyzed properly or analyzed with low
estimate or statistics are out of date

4.

Column is checked with different data type example Date_column =


12-31-2005 or varchar2_column = 12

5.

A function is used on the indexed column

6.

Optimizer computes cost of FULL table scan is cheaper than cost of


indexed access path

7.

Leading column of a composite index is not used in the predicate.

Beacon infotech Corporation


www.oracleact.com

50

2007-11-25

Oracle Performance Tuning

Beacon infotech Corporation


www.oracleact.com

51

2007-11-25