且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

[20131017]索引变大的问题.txt

更新时间:2022-09-06 23:19:14

[20131017]索引变大的问题.txt

昨天看别人的服务器,对方提示有一个表的索引很大,提议是否可以shrink减少大小,我仔细看发现这个表发现索引是一个sequence,也就
是线性增加的,但是看块里面的信息确实很空。突然想起Jonathan Lewis博客提到的情况,在并发大量插入的情况下,索引的ITL会占用
很多在分裂后依旧保持原有的数量,这样导致索引许多空间利用不上。

自己在做一些测试看看是否能模拟这个问题。

1.测试环境:
SCOTT@test> @ver
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production


SCOTT@test> create table t (id number,cr_date date,pad varchar2(20));
Table created.

SCOTT@test> create unique index i_t_id on t(id);
Index created.

create sequence scott.seq1 start with 1 increment by 1 minvalue 1 maxvalue 999999999999999999999999 cache 2000 nocycle order ;


2.建立文件ins.sql包含如下内容:
insert into t values (seq1.nextval,sysdate,'test');exec  dbms_lock.sleep(0.03);commit ;

复制1999行,在使用vim编辑如下:(^M => ctrl+v ctrl+m)
:%s/;/;^M/g
--最后加入quit。

建立一个shell脚本执行如下:
#! /bin/bash
for i in $(seq 20); do
 sqlplus scott/xxxx @ins.sql &
done


3.测试:
打开新的回话执行:
SQL> exec dbms_workload_repository.create_snapshot();
SYS@test> select * from v$sysstat where name like '%splits%';
STATISTIC# NAME                                CLASS         VALUE    STAT_ID
---------- ------------------------------ ---------- ------------- ----------
       412 leaf node splits                      128          8106 1417124053
       413 leaf node 90-10 splits                128          2627 1285138251
       414 branch node splits                    128           208  399027615
       415 root node splits                      128             8  708722985
       430 queue splits                          128             0 1168925905

--执行脚本后,等待全部结束:
$  . ins.sh

SQL> exec dbms_workload_repository.create_snapshot();

SYS@test> select * from v$sysstat where name like '%splits%';
STATISTIC# NAME                                CLASS         VALUE    STAT_ID
---------- ------------------------------ ---------- ------------- ----------
       412 leaf node splits                      128          8344 1417124053
       413 leaf node 90-10 splits                128          2766 1285138251
       414 branch node splits                    128           208  399027615
       415 root node splits                      128             8  708722985
       430 queue splits                          128             0 1168925905

--8344-8106=238
--2766-2627=139
--可以发现即使是插入线性增加的记录,索引分裂并没有90-10分裂。依旧存在一部分50-50分裂。

4.做一个转储看看:

SCOTT@test> select object_name,object_id,data_object_id from dba_objects where object_name='I_T_ID' and wner=user;
OBJECT_NAME           OBJECT_ID DATA_OBJECT_ID
-------------------- ---------- --------------
I_T_ID                   275000         275000

SYS@test> alter session set events 'immediate trace name treedump level 275000';
Session altered.

----- begin tree dump
branch: 0x1000213 16777747 (0: nrow: 194, level: 1)
   leaf: 0x1000215 16777749 (-1: nrow: 281 rrow: 281)
   leaf: 0x1000214 16777748 (0: nrow: 266 rrow: 266)
   leaf: 0x1000216 16777750 (1: nrow: 274 rrow: 274)
   leaf: 0x100022d 16777773 (2: nrow: 267 rrow: 267)
   leaf: 0x1000217 16777751 (3: nrow: 274 rrow: 274)
   leaf: 0x100022e 16777774 (4: nrow: 539 rrow: 539)
   leaf: 0x100022a 16777770 (5: nrow: 523 rrow: 523)
   leaf: 0x100022b 16777771 (6: nrow: 267 rrow: 267)
   leaf: 0x1000229 16777769 (7: nrow: 258 rrow: 258)
   leaf: 0x100022f 16777775 (8: nrow: 267 rrow: 267)
   leaf: 0x1000228 16777768 (9: nrow: 259 rrow: 259)
...
   leaf: 0x1000372 16778098 (180: nrow: 130 rrow: 130)
   leaf: 0x1000345 16778053 (181: nrow: 138 rrow: 138)
   leaf: 0x1000337 16778039 (182: nrow: 129 rrow: 129)
   leaf: 0x1000349 16778057 (183: nrow: 266 rrow: 266)
   leaf: 0x100034d 16778061 (184: nrow: 266 rrow: 266)
   leaf: 0x100033b 16778043 (185: nrow: 266 rrow: 266)
   leaf: 0x1000368 16778088 (186: nrow: 266 rrow: 266)
   leaf: 0x1000351 16778065 (187: nrow: 266 rrow: 266)
   leaf: 0x100037a 16778106 (188: nrow: 138 rrow: 138)
   leaf: 0x1000355 16778069 (189: nrow: 138 rrow: 138)
   leaf: 0x1000319 16778009 (190: nrow: 131 rrow: 131)
   leaf: 0x100033f 16778047 (191: nrow: 266 rrow: 266)
   leaf: 0x1000359 16778073 (192: nrow: 142 rrow: 142)
----- end tree dump

可以发现后面一些块保存的键值很少。


SYS@test> @dfb 1000372
old   2: dbms_utility.data_block_address_file(to_number('&1','xxxxxxxxxxxxxxxx')) rfile#,
new   2: dbms_utility.data_block_address_file(to_number('1000372','xxxxxxxxxxxxxxxx')) rfile#,
old   3: dbms_utility.data_block_address_block(to_number('&&1','xxxxxxxxxxxxxxxx')) block#
new   3: dbms_utility.data_block_address_block(to_number('1000372','xxxxxxxxxxxxxxxx')) block#
    RFILE#     BLOCK#
---------- ----------
         4        882

old   1: select 'alter system dump datafile '||dbms_utility.data_block_address_file(to_number('&1','xxxxxxxxxxxxxxxx'))||' block '||
new   1: select 'alter system dump datafile '||dbms_utility.data_block_address_file(to_number('1000372','xxxxxxxxxxxxxxxx'))||' block '||
old   2: dbms_utility.data_block_address_block(to_number('&&1','xxxxxxxxxxxxxxxx')) ||' ;' text
new   2: dbms_utility.data_block_address_block(to_number('1000372','xxxxxxxxxxxxxxxx')) ||' ;' text
TEXT
--------------------------------------------------------------------------------------------------------------------
alter system dump datafile 4 block 882 ;

SQL> alter system dump datafile 4 block 882 ;

Block header dump:  0x01000372
 Object id on Block? Y
 seg/obj: 0x43238  csc: 0x00.c16bf3b9  itc: 169  flg: E  typ: 2 - INDEX
     brn: 0  bdba: 0x1000301 ver: 0x01 opc: 0
     inc: 0  exflg: 0

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0014.002.000001f9  0x00c03989.0179.01  CB--    0  scn 0x0000.c16bf3b7
0x02   0x0003.019.0000337f  0x00c0315f.16c9.38  --U-    1  fsc 0x0000.c16bf3c9
0x03   0x0002.003.000032b5  0x00c03789.17af.23  --U-    1  fsc 0x0000.c16bf3ce
0x04   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x05   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x06   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x07   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x08   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x09   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x0a   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x0b   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x0c   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x0d   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x0e   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x0f   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x10   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x11   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x12   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x13   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x14   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x15   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x16   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x17   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x18   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x19   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x1a   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x1b   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x1c   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x1d   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x1e   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x1f   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
....
0x96   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x97   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x98   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x99   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x9a   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x9b   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x9c   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x9d   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x9e   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x9f   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0xa0   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0xa1   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0xa2   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0xa3   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0xa4   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0xa5   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0xa6   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0xa7   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0xa8   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0xa9   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000

SYS@test> @16to10 a9
16 to 10 DEC
------------
         169


--通过bbed观察也能说明问题:
BBED> set dba 4,882
        DBA             0x01000372 (16778098 4,882)

BBED> map /v
 File: /u01/app/oracle11g/oradata/test/users01.dbf (4)
 Block: 882                                   Dba:0x01000372
------------------------------------------------------------
 KTB Data Block (Index Leaf)

 struct kcbh, 20 bytes                      @0
    ub1 type_kcbh                           @0
    ub1 frmt_kcbh                           @1
    ub1 spare1_kcbh                         @2
    ub1 spare2_kcbh                         @3
    ub4 rdba_kcbh                           @4
    ub4 bas_kcbh                            @8
    ub2 wrp_kcbh                            @12
    ub1 seq_kcbh                            @14
    ub1 flg_kcbh                            @15
    ub2 chkval_kcbh                         @16
    ub2 spare3_kcbh                         @18

 struct ktbbh, 4080 bytes                   @20
    ub1 ktbbhtyp                            @20
    union ktbbhsid, 4 bytes                 @24
    struct ktbbhcsc, 8 bytes                @28
    sb2 ktbbhict                            @36
    ub1 ktbbhflg                            @38
    ub1 ktbbhfsl                            @39
    ub4 ktbbhfnx                            @40
    struct ktbbhitl[169], 4056 bytes        @44

 struct kdxle, 32 bytes                     @4108
    struct kdxlexco, 16 bytes               @4108
    sb2 kdxlespl                            @4124
    sb2 kdxlende                            @4126
    ub4 kdxlenxt                            @4128
    ub4 kdxleprv                            @4132
    ub1 kdxledsz                            @4136
    ub1 kdxleflg                            @4137

 sb2 kd_off[130]                            @4140

 ub1 freespace[2039]                        @4400

 ub1 rowdata[1689]                          @6439

 ub4 tailchk                                @8188

--  struct ktbbhitl[169], 4056 bytes        @44
--  说明索引itl槽非常多。每个占用24字节 24*169=4056,占一半空间。