数据库索引原理(oracle10g宝典17章读书笔记)
2016-01-01 17:36
387 查看
17.1概述
索引是一种与表相关的可选方案对象。索引无论逻辑上还是物理上都不依赖于相应的表。通过创建索引可以为数据检索提供快捷存取路径,较少查询时I/O操作,加快数据的检索速度。
索引需要占用实际的存储空间。
创建或者删除索引不会影响到数据库中的表、数据库或者其他索引(独立性)。
删除一个索引后任何应用程序都能够继续正常工作,唯一的影响就是某些查询的速度会变慢。
索引一旦被创建,那么执行数据库的 DML 操作时,Oracle会自动对索引进行维护。
用户完全不需要在 SQL 中制定使用哪个索引,如何使用索引,无论表上是否创建了索引,编写和使用SQL语句都是一样的。
17.1.1 作用
引入索引是为了在有条件查询的情况下加快检索速度,减少I/O操作的开销。17.1.2 索引的原理(标准索引)[位图索引不再详述]
ROWID: 伪列,表示对应记录的物理存储位置。上例子:
下表为 emp表的数据及其 rowid伪列值
员工号 | 名字 | 薪水 | 部门号 | 存储位置 |
---|---|---|---|---|
EMPNO | NAME | SAL | DEPTNO | ROWID |
1 | SMITH | 800 | 20 | AAAMZJAAEAAAAIVAAA |
2 | ALLEN | 1600 | 30 | AAAMZJAAEAAAAIVAAB |
3 | WARD | 1250 | 20 | AAAMZJAAEAAAAIVAAC |
4 | JONES | 1900 | 20 | AAAMZJAAEAAAAIVAAD |
5 | MARTIN | 2850 | 30 | AAAMZJAAEAAAAIVAAE |
6 | BLAKE | 2000 | 40 | AAAMZJAAEAAAAIVAAF |
7 | CLARK | 2500 | 40 | AAAMZJAAEAAAAIVAAG |
SELECT SAL FROM EMP WHERE NAME = ‘JONES’;
在name列上没有索引的情况下,就必须搜索所有记录,然后进行比较where 条件是否满足。因为即使找到了jones ,也不能保证就只有一个 jones ,所以必须全表扫描。
如果使用如下语句:
CREAT INDEX idx_emp_name ON EMP(NAME);
就会在emp表的name列上创建索引 idx_emp_name 。
创建索引时,Oracle 会对emp 表执行一次全表搜索,获取每条记录的 name 列的数据,并将他们按升序排列(默认升序),然后将排序后的name列的数据与对应记录的 ROWID相匹配存储到索引段中,如下表:
emp表的name列上创建的索引:
只包含 (索引列值,ROWID) ,这种组合被称为 “索引条目”。
NAME | ROWID |
---|---|
ALLEN | AAAMZJAAEAAAAIVAAB |
BLAKE | AAAMZJAAEAAAAIVAAF |
CLARK | AAAMZJAAEAAAAIVAAG |
JONES | AAAMZJAAEAAAAIVAAD |
MARTIN | AAAMZJAAEAAAAIVAAE |
SMITH | AAAMZJAAEAAAAIVAAA |
WARD | AAAMZJAAEAAAAIVAAC |
在 where 条件中出现的列往往就是要创建索引的列。
17.1.3索引的分类
用来创建索引的列被称为“索引列”1、单列索引 与 复合索引(按索引列数量来分)
2、唯一索引与非唯一索引 (按索引列值是否可重复来分)
3、标准索引 和 位图索引 (按索引数据组织形式)
标准索引(B-tree index,B树索引)
位图索引(bitmap index)
5、函数索引(function index)
17.1.4索引的存储管理
1、指定表空间创建索引时如果不使用 tablespace 选项,Oracle 将自动在用户的默认表空间中创建索引段;索引段为索引提供存储空间。
使用 tablespace 选项,可以使索引放在不同的表空间, 甚至 保存在 不同硬盘的表空间中,则可以减少硬盘的 I/O冲突,提高系统的存取性能,因为Oracle可以并行读取不同硬盘中的数据。
2、指定区分配方式 (意义不大)
创建索引时,可以使用 storage子句 指定存储空间的 “区分配方式”,但是可以指定的参数只有 initial ,即创建索引段时非配的第一个区的大小。
3、指定空闲空间管理方式
pctfree :(空闲空间比率)指定 “ 为更新操作而预留的空闲空间百分比”。
pctfree 较小 可以节约存储空间, 适用于 很少改变的 索引段。
pctfree 较大 时 可以提升更新性能,适用于频繁更新的索引段。
17.2管理索引的策略
双刃剑,可以提高数据检索效率,又会影响DML操作性能,因为要维护索引数据。早起SQL标准中采用了索引技术,新的SQL标准中并不提倡使用索引,而是建议在创建的时候直接用主键取而代之。
17.2.1选择合适的索引类型
1、列的基数属性位图索引适用于 基数比较小的列。通常基数只达到表中记录数的 1% 或者 列中的 大部分数值都重复出现 100次以上 ,则对应列应当建立 位图索引。
此外,某些列虽然具有比较高的 基数 ,同时也不会出现很多重复值,但是如果他们会经常被具有逻辑(and 和 or)查询条件的where 子句引用,那么也应当为他们创建位图索引。
而 B树索引适用于较高基数,大部分都不重复。
2、列的 NULL值特性
在位图中索引中可以记录具有NULL值的列,而在 B树索引中忽略所有 NULL 值,所以查询 与 NULL相关的查询,应当建立位图索引。
3、是否需要节省存储空间
B书索引 会占用较多 存储空间,位图索引存储空间要少得多。
4、查询条件的逻辑运算特性
逻辑运算 ,位图优先
5、查询条件的比较运算符特性
B树索引 适用于 比较大小 ,比如 > , < .
17.2.2在适当的表,适当的列上创建适当数量的索引
1、一般不要为很小的表创建索引2、应当为大部分列值不重复的列创建索引
3、对于取值范围(基数)很大的列(比如姓名列),应当创建B树索引;对于取值范围很小的列(比如性别),应当创建 位图索引。
4、对于包含很多null值,但是经常需要查询所有非null值记录的列,应当建立索引,若不会经常查询所有非 null值记录的列,没必要创建索引。 同时为了利用这个索引,查询条件需要适当的调整。例如 假设 col1 就是符合符合条件的列字段:
原来查询条件是:
select * from table where col1 is not null
现在最好使用下面查询条件:
select * from table where col1 > -9.99 * power (10,125)
5、不能在 long 或 blob 等大对象数据类型的列上创建索引。
6、对于经常需要连接(join)查询的多个表来说,在用于连接的列上创建索引可以显著提高查询速度。
7、Oracle 会自动为具有 primary key 约束 和 unique 约束的列创建索引,但是却不会自动为 foreign key 创建索引,所以有时候用户需要为连接查询中使用到的外键列创建索引。
17.2.3合理设置复合索引中的列顺序
创建复合索引时,虽然索引字段的顺序不受任何限制,但是索引的使用效率会收到索引字段顺序的影响,Oracle在决定是否使用索引时会看查询条件中的列出现的次序是否符合索引中出现的次序,而且要看是否是索引的前导子集。所以通常应该遵循的法则是,将最常查询的的 列 放在其他列的前面。
建立符合索引 (col1,col2,col3)
col1 启用
col1,col2 启用
col2 不启用
col2,col3 不启用
17.2.4设置合适的pctfree参数 (空闲空间比率)
索引对数据块的使用与表类似,都必须在数据块中保留由 PCTFREE 参数所指定的空闲空间。但是索引对这些空闲空间的使用方式与表有所不同。
对于表来说,只有更新操作会增加记录大小的时候,才会使用数据块中的空闲空间;
而对于索引来说,当向表中插入记录时,会将新增记录所对应的索引条目保存到相应(由列的索引顺序所决定)数据块的保留空间中。
可见,如果需要经常对某个表执行插入操作,就应该为这个表的索引设置 一个较高的 PCTFREE 参数,以便保留更多地空闲空间。
17.2.5设置合适的表空间
默认情况,索引与相应的表保存在同一个表空间中,但是 索引完全可以保存到其他表空间中,只需要在创建时显示地指明表空间。放在同一表空间,对于维护数据(比如备份)来说比较便利,并且 ,索引与表 永远都是 同时处于联机状态或者脱机状态,这样对应用程序提供较高的可用性。
放在不同表空间 甚至 保存在 不同硬盘的表空间中,则可以减少硬盘的 I/O冲突,提高系统的存取性能。
17.2.6设置合适的选项
UNIQUE :指定索引列 的列值必须是唯一的。默认不启用REVERSE :按逆序存储索引块的字节,不包括 ROWID。默认不启用
PARALLEL:使用多个服务进程创建索引,提高创建速度。默认不启用
NOLOGGING:不产生重做日志信息。默认不启用
ONLINE:创建过程中,允许 DML操作。默认不启用
17.2.7装载数据后再创建索引
有时候用户会在创建完索引后再使用 SQL*Loader 或者Import等工具,将保存在操作系统文件中的数据装载到表中。建议 在装载完数据之后再 创建索引。
17.3创建索引
语法:CREAT [UNIQUE] | [BITMAP] INDEX index_name
NO table_name([colm1 [ASC | DESC],colm2 [ASC | DESC],…] | [EXPRESS])
[TABLESPACE SPACE_NAME]
[PCTFREE N1]
[STORAGY (INITIAL N2)]
[NOLOGGING]
[ONLINE]
[PARALLEL]
为同一个表创建索引,要求列的组合必须不同,下面三个都是合法的,第二和第三顺序不同。
creat index index_name1 on emp(name);
creat index index_name2 on emp(name,job);
creat index index_name3 on emp(job,name);
creat index index_name4 on emp(job,name); 不合法
在相同的列上 创建不同类型的索引也是不合法的。
比如 创建了一个 B树索引,又想创建 位图索引 就不合法。
相关文章推荐
- Oracle raw数据类型
- oracle删除用户和表空间
- AIX环境下oracle重启
- oracle表空间自动扩展
- ORACLE ORA-01653: unable t…
- 卸载 Oracle 的 JDK
- Oracle 11g R2安装手册(图文教程)For Windows
- 大表添加字段时需要注意default问题
- ORACLE 重做日志
- 【翻译自mos文章】在Oracle单机数据库中定义database service
- ORACLE ROWNUM解析[转]
- Oracle表分区
- Oracle高级查询,GROUP BY
- Oracle高级查询,over 用法
- 完全卸载oracle11g
- Oracle用imp导入出现ora-20000错误
- Oracle job procedure
- Oracle用imp和exp导入导出数据库
- 表分区
- Oracle数据库备份与恢复--Windows批处理+定时任务计划(V1.0)