Oracle热爱者的天地

 

 

昆鹏数据恢复中心——技术引导未来,服务创造价值!

关于索引的检验  之二

【索引的构造】
表 TEST01 里有 EMPNO01 和 EMPNO02 字段,包含相同的数据值。在 EMPNO01 字段上创建索引。让存放在 EMPNO01 和 EMPNO02 字段中的数据从 10000010 开始以 10 为单位增加,直到 10100000 为止,共计 10000 条记录。 表 TEST01 如下图所示:

分别在 EMPNO01 字段和 EMPNO02 字段附加查询条件对该表进行如下查询:
1. 查询第 5000 条数据
2. 查询前 5000 条数据
EMPNO01 字段(有索引)和 EMPNO02 字段(没有索引),执行后的结果如下图所示:


上图的 (※2) 、 (※3) 、 (※4) 是利用统计 I/O 次数的 SQL 语句,求出执行以上查询前后的 I/O 统计结果。

【统计 I/O 次数的 SQL 语句】

*************************************************************

SELECT SUBSTR(A.NAME, INSTRB(A.NAME, '../', -1) + 1, 20) FILE_NAME

,A.STATUS

,TO_CHAR(B.PHYRDS, '99999999999990') PHYRDS

FROM V$DATAFILE A, V$FILESTAT B

WHERE A.FILE# = B.FILE# ;

*************************************************************

请大家注意检索结果中【检索 1 】的查询条件是以索引( EMPNO01 )进行唯一查询。前面已经介绍过 “ 索引的构造 ” 知识,索引是经过根、枝、叶三阶段抵达目的记录,这种查询对于索引的数据块只会发生 2 次 I/O ,表 TEST01 数据只有 1 万条记录,所以只用到第二次 I/O 。我们可以用下面的 ANALYZE 命令确认这件事情。

*************************************************************

SQL> ANALYZE INDEX TEST01 VALIDATE STRUCTURE ;

└→ 不是表名称而是索引名称

*************************************************************

分析结果如下:

*************************************************************

SQL> SELECT HEIGHT, -- 枝节点的阶层有多高

2 BLOCKS, -- 全数据块数

3 LF_ROWS, -- 叶行数

4 LF_BLKS, -- 叶数据块数

5 BR_ROWS, -- 枝行数

6 BR_BLKS -- 枝数据块数

7 FROM INDEX_STATS ;

*************************************************************

*************************************************************

HEIGHT BLOCKS LF_ROWS LF_BLKS BR_ROWS BR_BLKS

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

2 51200 10000 87 86 1

*************************************************************

请大家注意上面的数据块数总数( BLOCKS ) ” 结果是 51200 ,叶数据块与枝数据块总计是 88 个。这是因为以 CREATE INDEX 创建索引的时候,为了不让 extent 存在未使用数据块以及因为索引的 “ 空间管理机制 ” 、 “ 性能优先 ” 所衍生的未使用数据块,而让索引的初始化空间为 100 M 所造成的。

接下来请大家注意【检索 3 】的查询条件使用索引( EMPNO01 )进行的范围检索。这里对于索引进行了 45 次 I/O ,从第 1 条的值 10000010 到第 5000 条的值 10050000 存放在总共 44 个叶数据块,加上 1 个枝数据块的值。下次介绍的 TREEDUMP 功能就可以确认这个部分。

上次对 1 万笔数据的表进行了 1 ~ 5000 笔(一半)的范围检索,结果对索引发生了 45 次 I/O 。这次我们要以 TREEDUMP 功能确认结果。
要取得 TREEDUMP ,首先必须知道索引的 OBJECT_ID 才行。要知道 OBJECT_ID ,请用下面的 SELECT 语句。

*************************************************************

SELECT OBJECT_NAME,

OBJECT_ID

>FROM USER_OBJECTS WHERE OBJECT_TYPE = 'INDEX' ;

 

OBJECT_NAME OBJECT_ID

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

ID_EMP 3461

PK_DEPT 1924

PK_EMP 1926

TEST01 3539

*************************************************************

接下来,指定 OBJECT_ID 取得 TREEDUMP 。

*************************************************************

ALTER SESSION SET EVENTS

'IMMEDIATE TRACE NAME TREEDUMP LEVEL 3539' ;

└→ 分配给 TEST01 的 OBJECT_ID

*************************************************************

此外, TREEDUMP 的输出目的地是数据库初始化参数 user_dump_dest 指定的目录位置,文件名为 ora_xxxx.trc ,其中的最新版本即是当前运行命令后生成的。

*************************************************************

【 TREEDUMP 】

----- begin tree dump

branch: 0x5800003 92274691 (0: nrow: 87, level: 1) (1)

leaf: 0x2000004 33554436 (-1: nrow: 116) ↑

leaf: 0x2000005 33554437 (0: nrow: 116) |

leaf: 0x2000006 33554438 (1: nrow: 116) |

leaf: 0x2000007 33554439 (2: nrow: 116) |

leaf: 0x2000008 33554440 (3: nrow: 116) |

: |

: |

leaf: 0x2000018 33554456 (19: nrow: 116) |

leaf: 0x2000019 33554457 (20: nrow: 116) |

leaf: 0x 200001a 33554458 (21: nrow: 116) |

leaf: 0x200001b 33554459 (22: nrow: 116) |

leaf: 0x 200001c 33554460 (23: nrow: 116) |

leaf: 0x200001d 33554461 (24: nrow: 116) | (3)

leaf: 0x200001e 33554462 (25: nrow: 116) |

leaf: 0x 200001f 33554463 (26: nrow: 116) |

leaf: 0x2000020 33554464 (27: nrow: 116) |

leaf: 0x2000021 33554465 (28: nrow: 116) |

leaf: 0x2000022 33554466 (29: nrow: 116) |

leaf: 0x2000023 33554467 (30: nrow: 116) |

leaf: 0x2000024 33554468 (31: nrow: 116) |

leaf: 0x2000025 33554469 (32: nrow: 116) |

leaf: 0x2000026 33554470 (33: nrow: 116) |

: |

: |

leaf: 0x200002d 33554477 (40: nrow: 116) |

leaf: 0x200002e 33554478 (41: nrow: 116) |

leaf: 0x 200002f 33554479 (42: nrow: 116) (2)

leaf: 0x2000030 33554480 (43: nrow: 116)

leaf: 0x2000031 33554481 (44: nrow: 116)

leaf: 0x2000032 33554482 (45: nrow: 116)

leaf: 0x2000033 33554483 (46: nrow: 116)

leaf: 0x2000034 33554484 (47: nrow: 116)

:

:

leaf: 0x2000058 33554520 (83: nrow: 116)

leaf: 0x2000059 33554521 (84: nrow: 116)

leaf: 0x 200005a 33554522 (85: nrow: 24)

↑ ↑

Leaf No. 键的数量

----- end tree dump

*************************************************************

(1) 读取枝数据块,求出存放了第 5000 笔的值 10050000 的 DBA 。
(2) 读取存放了第 5000 笔的值 10050000 的叶数据块的号码 42 。
(3) 其后的数据块都符合条件式( EMPNO01 <= 10050000 ),所以会读取叶资料块号码 42 ~ - 1 的数据块。

◎ 检索的过程如图 :

下次我们会让表的数据增加到 100 万件,看看出现多次叶分割的情况。


 

关于问题专区

我们很乐意回答大家的问题,如果您对于 Oracle 性能有任何疑问,只要我们能给出对您有价值的情报,一定会与您分享。欢迎大家尽量发问,我们会在今后的内容中回答您的问题!请您把问题发送到 这里 。QQ:9417901

 

昆鹏数据恢复中心介绍

昆鹏数据恢复中心于 2004 年创立于沈阳浑河北岸的三好街高新技术产业区里,业务遍布中国和日本。集项目研究、应用、实施、销售、服务于一体,为客户提供管理咨询、大型应用系统的性能优化、软件研发等一体化技术服务。昆鹏数据恢复中心由资深软件行业专家、优秀的技术开发队伍和具备先进理念的管理团队形成核心力量,具有丰富的项目管理经验和雄厚的技术实力。

 

昆鹏数据恢复中心服务内容                                         

磁盘阵列数据恢复

Oracle数据库恢复