索引存储及使用原理
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
clustering_factor 是表征表中数据的存储顺序和某索引字段顺序的符合程度。
一、索引的存储结构
索引是一种允许直接访问数据表中某一数据行的树型结构,为了提高查询效率而引入,是一个独立于表的对象,可以存放在与表不同的表空间中。索引记录中存有索引关键字和指向表中数据的指针(地址)。对索引进行的I/O 操作比对表进行操作要少很多。索引一旦被建立就将被Oracle系统自动维护,查询语句中不用指定使用哪个索引。
分类可以按逻辑设计和物理实现来分类。
索引逻辑分类
单列索引:基于一列的操作
多列索引:组合索引,最多为32列。组合索引的列不一定与表中列顺序相同。
惟一索引:列的值各不相同。
非惟一索引:列的值允许相同。
基于函数的惟一索引:利用表中一列或多列基于函数表达式所创建的索引。既可以是B-树,也可以是位图索引。
索引物理分类
分区或非分区索引,非分区既可以是B-树,也可以是位图索引。
B-树:包括正常或反转关键字索引,反转关键字在数据库优化中介绍。
位图索引
B-树索引
索引的存储方式
虽然所有索引都使用B 树结构,但术语“B 树索引”通常与存储每个关键字的行标识列表的索引关联。
B 树索引结构
至上而下,是根结点、分枝结点及叶子结点,叶子结点中有指向表中数据行的索引行。叶子结点被双向链表在一起,以方便按索引关键字升序或降序扫描。
索引的顶部为根,其中包含指向索引中下一级的项,下一级为分枝块,分枝块又指向索引中下一级的块,最低一级为叶节点,其中包含指向表行的索引项。叶块为双重链接,有助于按关键字值的升序和降序扫描索引。
索引项叶节点的格式
索引项由以下三部分组成:
? 项标题(entry header),存储列数和锁定信息
? 关键字列的“长度- 值”(length-value pairs) ,必需成对出现,定义了列长度,紧跟在列长度之后的就是列的值。
? 行的行标识(RowID),包含关键字值。
索引项叶结点的特征
在非分区表上的B 树索引中:
? 如果多行具有相同的关键字值,并且索引没有被压缩,则关键字值重复存放。
? 没有索引项与所有关键字列都为NULL 的行对应,即如果某列值为Null,则不存储相应的索引项。如果Where子句中索引的所在列值为null,Oracle将不使用索引进行全表扫描。
? 因为所有行都属于同一段,所以使用受限行标识指向表中的行,使用RowID可以节省索引存储空间。
DML 操作对索引的影响
当在表上执行DML 操作时,Oracle 服务器将自动维护所有的索引,下面解释DML命令对索引的影响:
? 插入(Insert)操作导致在适当的块中插入索引项。
? 删除(Delete)行只导致逻辑删除索引项,删除的行所用的空间不能用于新项,直到删除块中的所有项。
? 更新(Update)操作将选删除,再插入,除了在创建时,其它任何时候PCTFREE 设置对索引都没有影响,即使索引块空间少于PCTFREE 指定的空间,仍可以向索引块添加新项。
二、查询使用索引探索:
§1.1 简介
本文简要介绍了CBO成本计算的基本原理,并初步解释了初始化参数optimizer_index_cost_adj和db_file_multiblock_read_count对CBO的影响。
数据库版本为Oracle 9.0.1
平台为Windows2000
system@FXSB01> select *from v$version;
BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.0.1.1.1 - Production
PL/SQL Release 9.0.1.1.1 - Production
CORE 9.0.1.1.1 Production
TNS for 32-bit Windows: Version 9.0.1.1.0 - Production
NLSRTL Version 9.0.1.1.1 – Production
§1.2 建立测试数据
system@FXSB01> @conn test/test@test
已连接。
test@FXSB01> -- 建立执行计划表
test@FXSB01> @%ORACLE_HOME%\rdbms\admin\utlxplan.sql 表已创建
test@FXSB01>
test@FXSB01> -- 建立测试表
test@FXSB01> -- 表1,2除索引列外有其他列,表3没有其他列
test@FXSB01> drop table test1
2 /
表已丢弃。
test@FXSB01> create table test1
2 (
3 n1 number(10),
4 c1 char(100)
5 )
6 /
表已创建。
test@FXSB01> drop table test2
2 /
表已丢弃。
test@FXSB01> create table test2
2 (
3 n1 number(10),
4 c1 char(100)
5 )
6 /
表已创建。
test@FXSB01> drop table test3
2 /
表已丢弃。
test@FXSB01> create table test3
2 (
3 n1 number(10)
4 )
5 /
表已创建。
test@FXSB01> -- 插入test1唯一值
test@FXSB01> begin
2 for i in 1..5000 loop
3 insert into test1 values(i,'test');
4 end loop;
5 end;
6 /
PL/SQL 过程已成功完成。