楼主: grassbell

[精华] 关于索引(index)的中度理解,请指正!

[复制链接]
招聘 : 数据库管理员
论坛徽章:
21
授权会员
日期:2005-10-30 17:05:332012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:36马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:11:36
11#
 楼主| 发表于 2004-7-3 22:20 | 只看该作者
此文只是从表象对一般索引做了阐述。希望大家能从其他方面提出自己的观点,继续作深入讨论。

使用道具 举报

回复
论坛徽章:
1
授权会员
日期:2005-10-30 17:05:33
12#
发表于 2004-7-5 16:28 | 只看该作者
请问grassbell版主:

你的trace文件的内容怎么跟我的不一样呢?我的trace文件(WindowsNT和solaris操作系统)内容都很少,例如:

/oradata/hsccs//admin/hsccs/udump/hsccs_ora_16856.trc
Oracle9i Enterprise Edition Release 9.2.0.1.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.1.0 - Production
ORACLE_HOME = /oracle/product
System name:    SunOS
Node name:      hscc1
Release:        5.9
Version:        Generic_112233-08
Machine:        sun4u
Instance name: hsccs
Redo thread mounted by this instance: 1
Oracle process number: 32
Unix process pid: 16856, image: oracle@hscc1 (TNS V1-V3)

*** 2004-07-05 14:36:21.472
*** SESSION ID89.50572) 2004-07-05 14:36:21.447
Start dump data blocks tsn: 9 file#: 9 minblk 26 maxblk 26
buffer tsn: 9 rdba: 0x0240001a (9/26)
scn: 0x0000.02c974f3 seq: 0x02 flg: 0x04 tail: 0x74f32102
frmt: 0x02 chkval: 0x0794 type: 0x21=SECOND LEVEL BITMAP BLOCK
Dump of Second Level Bitmap Block
   number: 1       nfree: 1       ffree: 0      pdba:     0x0240001b
  opcode:0
xid:
  L1 Ranges :
  --------------------------------------------------------
   0x02400019  Free: 5 Inst: 1
  
  --------------------------------------------------------
End dump data blocks tsn: 9 file#: 9 minblk 26 maxblk 26


还有一个问题:关于你的  对RBO/CBO运行机制的中度理解 http://www.itpub.net/showthread. ... 0%B6%C8%C0%ED%BD%E2

SQL>explain plan for select ... where...
SQL>select * from table(dbms_xplan.dispay)
查看的内容也没有statistics部分,如:

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------

--------------------------------------------------------------------
| Id  | Operation            |  Name       | Rows  | Bytes | Cost  |
--------------------------------------------------------------------
|   0 | SELECT STATEMENT     |             |    14 |   392 |     5 |
|*  1 |  HASH JOIN           |             |    14 |   392 |     5 |
|   2 |   TABLE ACCESS FULL  | DEPT        |     4 |    44 |     2 |
|   3 |   TABLE ACCESS FULL  | EMP         |    14 |   238 |     2 |
--------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("E"."DEPTNO"="D"."DEPTNO"

Note: cpu costing is off


谢谢了!

使用道具 举报

回复
招聘 : 数据库管理员
论坛徽章:
21
授权会员
日期:2005-10-30 17:05:332012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:36马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:11:36
13#
 楼主| 发表于 2004-7-5 18:20 | 只看该作者
1)你确定你的执行过程是这样的吗?

[php]
SQL> select file_id,extent_id,block_id,blocks from dba_extents where segment_name='TI';

   FILE_ID  EXTENT_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
         3          0        249          8

'block 249是segment header,BLOCK 250 开始存储索引的第一个leaf note'

SQL> alter system dump datafile 3 block 250;

System altered.
[/php]

还有我注意到你的trace是Dump of Second Level Bitmap Block。。。

2)我用的是
SQL> set autotrace on;

使用道具 举报

回复
论坛徽章:
1
授权会员
日期:2005-10-30 17:05:33
14#
发表于 2004-7-6 11:09 | 只看该作者

谢谢

1. oracle92010 for solaris 和oracle92010 for windowsNT dump出来的trace文件内容都是一样的,type: 0x21=SECOND LEVEL BITMAP BLOCK
  但是oracle81700 for solaris dump出来的trace文件 type: 0x06=trans data ,跟你的结果一致

2. 使用 set autotrace on就可以了

使用道具 举报

回复
招聘 : 数据库管理员
论坛徽章:
66
ITPUB元老
日期:2005-07-16 18:49:11授权会员
日期:2005-10-30 17:05:33ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44现任管理团队成员
日期:2011-05-07 01:45:08版主3段
日期:2012-05-15 15:24:11
15#
发表于 2004-8-29 18:37 | 只看该作者
最初由 grassbell 发布
[B]1)索引的root,branch,leaf;

~~~Leaf~~~

[php]
SQL> create table t(x char(1024));

Table created.

SQL> create index ti on t(x);

Index created.

SQL> insert into t values(1);

1 row created.

SQL> commit;

Commit complete.

SQL> select file_id,extent_id,block_id,blocks from dba_extents where segment_name='TI';

   FILE_ID  EXTENT_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
         3          0        249          8

'BLOCK 250 开始存储索引的第一个leaf note'

SQL> alter system dump datafile 3 block 250;

System altered.
[/php]
'trace...'
kdxledsz 0
kdxlebksz 8036
row#0[7001] flag: -----, lock: 2
col 0; len 1024; (1024):  'indexed data value(1024B),第一个31代表1'
31 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 1; len 6; (6):  00 c0 00 da 00 00  'RowID(6B)'
----- end of leaf block dump -----

index leaf note每个entry有5列:
row header(3B)|length(1B)|indexed data value(1024B)|length(1B)|RowID(6B)
这样每个row的大小为:3+1+1024+1+6=1035
db_block_size=8192,
block的默认pct_free=10%,
所以每个block能存储7个rows:
[php]
SQL> select 8192*0.9/1035 from dual;

8192*0.9/1035
-------------
   7.12347826

'再插入6row的数据:'

SQL>begin
  2 for i in 2..7 loop
  3     insert into t values(i);
  4 end loop;
  5 end;
  6 /

PL/SQL procedure successfully completed.

SQL> commit;

Commit complete.

SQL> ANALYZE INDEX TI VALIDATE STRUCTURE;

Index analyzed.

SQL> select btree_space,used_space,pct_used,blocks,lf_blks,br_blks from index_stats;

BTREE_SPACE USED_SPACE   PCT_USED     BLOCKS    LF_BLKS    BR_BLKS
----------- ---------- ---------- ---------- ---------- ----------
       8000       7259         91          8          1          0        '只有一个leaf note,没有branch note'

SQL> alter system dump datafile 3 block 250;

System altered.
[/php]
'trace...'
kdxlebksz 8036
row#0[7001] flag: -----, lock: 0
col 0; len 1024; (1024): '31代表1'
31 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 1; len 6; (6):  00 c0 00 da 00 00
row#1[5966] flag: -----, lock: 2
col 0; len 1024; (1024): '32代表2'
32 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
...
...
row#6[791] flag: -----, lock: 2
col 0; len 1024; (1024): '37代表7'
37 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 1; len 6; (6):  00 c0 00 da 00 06
----- end of leaf block dump ----- [/B]


你是说索引中的rowid是6b,那是否可以根据这个
rowid求出file_id/obj_id/block_id/row_id?偶做了一个
简单的测试
01 40 01 78 00 00
0000 0001 01
5
00 0000 0000 0001 0111 1000
376

0000 0000 0000 0000
0

前10 bit代表了file_id
中22 bit代表了block_id
后16 bit代表了row_id

奇怪的是,为什么索引中的rowid不能直接找到obj_id?
通过dump file_id=5/block_id=376
发现该块中存储的是0x3268,即创建该索引的表


buffer tsn: 7 rdba: 0x014001a5 (5/421)
scn: 0x0000.003c04d7 seq: 0x01 flg: 0x04 tail: 0x04d70601
frmt: 0x02 chkval: 0xd352 type: 0x06=trans data
Block header dump:  0x014001a5
Object id on Block? Y
seg/obj: 0x3269  csc: 0x00.3c04d2  itc: 2  flg: E  typ: 2 - INDEX
     brn: 0  bdba: 0x14001a1 ver: 0x01 opc: 0
     inc: 0  exflg: 0

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.003c04d2

Leaf block dump
===============
header address 196782692=0xbbaaa64
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 485
kdxcofbo 1006=0x3ee
kdxcofeo 1830=0x726
kdxcoavs 824
kdxlespl 0
kdxlende 0
kdxlenxt 20971942=0x14001a6
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 8032
row#0[8020] flag: ------, lock: 0, len=12
col 0; len 2; (2):  c1 02
col 1; len 6; (6):  01 40 01 78 00 00
row#1[8008] flag: ------, lock: 0, len=12
col 0; len 2; (2):  c1 03
col 1; len 6; (6):  01 40 01 78 00 01
row#2[7996] flag: ------, lock: 0, len=12
col 0; len 2; (2):  c1 04
col 1; len 6; (6):  01 40 01 78 00 02
row#3[7984] flag: ------, lock: 0, len=12
col 0; len 2; (2):  c1 05
col 1; len 6; (6):  01 40 01 78 00 03
row#4[7972] flag: ------, lock: 0, len=12
col 0; len 2; (2):  c1 06
col 1; len 6; (6):  01 40 01 78 00 04
row#5[7960] flag: ------, lock: 0, len=12
col 0; len 2; (2):  c1 07
col 1; len 6; (6):  01 40 01 78 00 05
row#6[7948] flag: ------, lock: 0, len=12
col 0; len 2; (2):  c1 08
col 1; len 6; (6):  01 40 01 78 00 06
row#7[7936] flag: ------, lock: 0, len=12
col 0; len 2; (2):  c1 09
col 1; len 6; (6):  01 40 01 78 00 07
row#8[7924] flag: ------, lock: 0, len=12
col 0; len 2; (2):  c1 0a
col 1; len 6; (6):  01 40 01 78 00 08
row#9[7912] flag: ------, lock: 0, len=12
col 0; len 2; (2):  c1 0b
col 1; len 6; (6):  01 40 01 78 00 09
row#10[7900] flag: ------, lock: 0, len=12
col 0; len 2; (2):  c1 0c
col 1; len 6; (6):  01 40 01 78 00 0a
row#11[7888] flag: ------, lock: 0, len=12
col 0; len 2; (2):  c1 0d
col 1; len 6; (6):  01 40 01 78 00 0b
row#12[7876] flag: ------, lock: 0, len=12
col 0; len 2; (2):  c1 0e
col 1; len 6; (6):  01 40 01 78 00 0c
row#13[7864] flag: ------, lock: 0, len=12
col 0; len 2; (2):  c1 0f
col 1; len 6; (6):  01 40 01 78 00 0d

Start dump data blocks tsn: 7 file#: 5 minblk 376 maxblk 376
buffer tsn: 7 rdba: 0x01400178 (5/376)
scn: 0x0000.003c04cb seq: 0x01 flg: 0x06 tail: 0x04cb0601
frmt: 0x02 chkval: 0x8f69 type: 0x06=trans data
Block header dump:  0x01400178
Object id on Block? Y
seg/obj: 0x3268  csc: 0x00.3c0439  itc: 2  flg: E  typ: 1 - DATA
     brn: 0  bdba: 0x1400171 ver: 0x01 opc: 0
     inc: 0  exflg: 0

Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0004.003.0000055f  0x00800072.02cc.52  --U-  357  fsc 0x0000.003c04cb
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000

data_block_dump,data header at 0xbbaaa64
===============
tsiz: 0x1f98
hsiz: 0x2dc
pbl: 0x0bbaaa64
bdba: 0x01400178
     76543210
flag=--------
ntab=1
nrow=357
frre=-1
fsbo=0x2dc
fseo=0x611
avsp=0x335
tosp=0x335

使用道具 举报

回复
论坛徽章:
86
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20咸鸭蛋
日期:2012-05-08 10:27:19版主8段
日期:2012-05-15 15:24:112013年新春福章
日期:2013-02-25 14:51:24
16#
发表于 2004-8-29 23:06 | 只看该作者
奇怪的是,为什么索引中的rowid不能直接找到obj_id?

-----

因为索引段对应的数据段在 一开始就知道,因为是先知道数据段才找到索引段,然后根据索引段内容去搜索数据段内容,所以索引段中 rowid 不必包含 data_object_id 信息

使用道具 举报

回复
招聘 : 数据库管理员
论坛徽章:
21
授权会员
日期:2005-10-30 17:05:332012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:362012新春纪念徽章
日期:2012-02-13 15:11:36马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:11:36
17#
 楼主| 发表于 2004-8-29 23:20 | 只看该作者
如果索引是建立在非分区表上,或者是分区表上的 LOCAL 索引,使用的是6 bytes的 Restricted ROWID ,原因如 biti 所云。

如果索引是建立在分区表上的 GLOBAL index,则使用 10bytes 的 Extended ROWID,这样可以区分索引指向哪个分区表。

使用道具 举报

回复
招聘 : 数据库管理员
论坛徽章:
66
ITPUB元老
日期:2005-07-16 18:49:11授权会员
日期:2005-10-30 17:05:33ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44现任管理团队成员
日期:2011-05-07 01:45:08版主3段
日期:2012-05-15 15:24:11
18#
发表于 2004-8-30 09:09 | 只看该作者
表中数据的每行都对应存在rowid吧,
为什么dump后不象索引段那样看到rowid呢?
即然表中的rowid是伪例,
那又是用什么算法产生rowid的呢?
通常使用rowid的单行查询最快?
又是什么原因呢?

使用道具 举报

回复
论坛徽章:
86
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20咸鸭蛋
日期:2012-05-08 10:27:19版主8段
日期:2012-05-15 15:24:112013年新春福章
日期:2013-02-25 14:51:24
19#
发表于 2004-8-30 11:59 | 只看该作者
最初由 xzh2000 发布
[B]表中数据的每行都对应存在rowid吧,
为什么dump后不象索引段那样看到rowid呢?
即然表中的rowid是伪例,
那又是用什么算法产生rowid的呢?
通常使用rowid的单行查询最快?
又是什么原因呢? [/B]


ft, sigh

比如你们家地址,人家可以根据地址找到你们家

但是你们家门口有 写上 你们家从省----市---  街道---门牌号  的地址吗?

即使这个写在你们家门口,对人家根据地址来找有用吗?没到你们家门口前 怎么知道呢?

使用道具 举报

回复
论坛徽章:
314
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
20#
发表于 2004-8-31 18:50 | 只看该作者
谁知道索引中,存储的ROWID的值代表的意义?
比如:
row#120[6081] flag: -----, lock: 0
col 0; len 3; (3):  c2 02 16
col 1; len 3; (3):  c2 21 14
col 2; len 6; (6):  03 40 00 1f 00 78  --> 应该是ROWID的值

00 78  -- 代表该记录在BLOCK块中行数
00 1f  --  代表的是BLOCK块数
但我始终看不出 03 40 代表什么?

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表