在关系数据库中,索引是一种与表有关的数据库结构,它可以使对应于表的sql语句执行得更快。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。
对于数据库来说,索引是一个必选项,但对于现在的各种大型数据库来说,索引可以大大提高数据库的性能,以至于它变成了数据库不可缺少的一部分。
索引分类:
逻辑分类
singlecolumnorconcatenated 对一列或多列建所引
uniqueornonunique 唯一的和非唯一的所引,也就是对某一列或几列的键值(key)是否是唯一的。
Function-based 基于某些函数索引,当执行某些函数时需要对其进行计算,可以将某些函数的计算结果事先保存并加以索引,提高效率。
Doman 索引数据库以外的数据,使用相对较少
物理分类
B-Tree:normalorreversekeyB-Tree索引也是我们传统上常见所理解的索引,它又可以分为正常所引和倒序索引。
Bitmap:位图所引,后面会细讲
B-Tree 索引
B-Treeindex也是我们传统上常见所理解的索引。B-tree(balancetree)即平衡树,左右两个分支相对平衡。
B-Treeindex
Root为根节点,branch为分支节点,leaf到最下面一层称为叶子节点。每个节点表示一层,当查找某一数据时先读根节点,再读支节点,最后找到叶子节点。叶子节点会存放indexentry(索引入口),每个索引入口对应一条记录。
Indexentry的组成部分:
Indexentryentryheader 存放一些控制信息。
Keycolumnlength 某一key的长度
Keycolumnvalue 某一个key的值
ROWID 指针,具体指向于某一个数据
创建索引:
用户登录: sql> conn as1/as1 Connected. 创建表: sql> create table dex (id int,sex char(1),name 10)); Table created. 向表中插入1000条数据 sqlbegin 2 for i in 1..1000 3 loop 4 insert into dex values(i,'M',0); line-height:1.5!important">chongshi'); 5 end loop; 6 commit; 7 end; 8 / PL/sql procedure successfully completed. 查看表记录 sqlselect * from dex; ID SE NAME ---------- -- --------------------
... . .....
991 M chongshi 992 M chongshi 993 M chongshi 994 M chongshi 995 M chongshi 996 M chongshi 997 M chongshi 998 M chongshi 999 M chongshi 1000 M chongshi 1000 rows selected. 创建索引: sqlindex dex_idx1 on dex(id); Index created. 注:对表的第一列(id)创建索引。 查看创建的表与索引 sqlselect object_name,object_type from user_objects; OBJECT_NAME OBJECT_TYPE ------------------------------------------------------------------------------ DEX TABLE DEX_IDX1 INDEX
索引分离于表,作为一个单独的个体存在,除了可以根据单个字段创建索引,也可以根据多列创建索引。Oracle要求创建索引最多不可超过32列。
sqlindex dex_index2 on dex(sex,name); Index created. sql> OBJECT_NAME OBJECT_TYPE ------------------------------------------------------------------------------ DEX TABLE DEX_IDX1 INDEX DEX_INDEX2 这里需要理解:编写一本书,只有章节页面定好之后再设置目录;数据库索引也是一样,只有先插入好数据,再建立索引。那么我们后续对数据库的内容进行插入、删除,索引也需要随之变化。但索引的修改是由oracle自动完成的。
上面这张图能更加清晰的描述索引的结构。
跟节点记录0至50条数据的位置,分支节点进行拆分记录0至10.......42至50,叶子节点记录每第数据的长度和值,并由指针指向具体的数据。
最后一层的叶子节是双向链接,它们是被有序的链接起来,这样才能快速锁定一个数据范围。
如:
from dex where id>23 and id<32; ID SE NAME -------- -- -------------------- 24 M chongshi 25 M chongshi 26 M chongshi 27 M chongshi 28 M chongshi 29 M chongshi 30 M chongshi 31 M chongshi 8 rows selected.创建索引的一些规则
1、权衡索引个数与DML之间关系,DML也就是插入、删除数据操作。
这里需要权衡一个问题,建立索引的目的是为了提高查询效率的,但建立的索引过多,会影响插入、删除数据的速度,因为我们修改的表数据,索引也要跟着修改。这里需要权衡我们的操作是查询多还是修改多。
2、把索引与对应的表放在不同的表空间。
当读取一个表时表与索引是同时进行的。如果表与索引和在一个表空间里就会产生资源竞争,放在两个表这空就可并行执行。
3、最好使用一样大小是块。
Oracle默认五块,读一次I/O,如果你定义6个块或10个块都需要读取两次I/O。最好是5的整数倍更能提高效率。
4、如果一个表很大,建立索引的时间很长,因为建立索引也会产生大量的redo信息,所以在创建索引时可以设置不产生或少产生redo信息。只要表数据存在,索引失败了大不了再建,所以可以不需要产生redo信息。
5、建索引的时候应该根据具体的业务sql来创建,特别是where条件,还有where条件的顺序,尽量将过滤大范围的放在后面,因为sql执行是从后往前的。(小李飛菜刀)
索引常见操作
改变索引:
sqlalter index employees_last _name_idx storage(next 400K maxextents 100);索引创建后,感觉不合理,也可以对其参数进行修改。详情查看相关文档
调整索引的空间:
新增加空间 sqlindex orders_region_id_idx allocate extent (size 200K datafile /disk6/index01.dbf'); 释放空间 sqlindex oraers_id_idx deallocate unused;