1. 说明
① 索引是数据库的对象之一,用于加快数据的检索,类似于书籍的索引。在数据库中索引可以减少数据库程序查询结果时所需要的读取的数据量,类似于在书籍中我们利用索引可以不用翻阅整本书即可找到想要的信息。
② 索引是建立在表上的可选对象;索引的关键在于通过一组排序后的索引键来取代默认的全表扫描方式,从而提高检索效率。
③ 索引在逻辑上和数据上都与相关的表和数据无关,当创建或者删除一个索引时,不会影响基本的表。
④ 索引一旦建立,在表上进行DML操作时(例如在执行插入、修改或者删除相关操作时),Oracle会自动管理索引,索引删除,不会对表产生影响。
⑤ 索引对用户是透明的,无论表上是否有索引,SQL语句的用法不变。
⑥ oracle创建主键时会自动在该列创建索引。
2. 索引原理
① 如果没有所以,搜索记录时需要搜索所有的记录(例如查找“name = ‘wish’”),因为不能保证满足条件的结果只有一条,所以需要全部搜索一遍。
② 若在name上建立索引,Oracle会对全表进行一次搜索,将每条记录的name值按照顺序排列,然后构建索引条目(name和rowID),存储到索引段中,查询时可以直接查找到对应地方。
③ 创建了索引不一定就会使用,oralce自动统计表的信息后,决定是否使用索引,表中数据很少时使用全表扫描已经很快,没有必要使用索引。
3. 索引使用
创建、修改、删除、查看。
① 创建索引语法
create [unique] | [bitmap] index index_name --unique表示唯一索引 bitmap创建位图索引
on table_name([column1 [asc|desc], --asc|desc表示字段按照升序或者降序排列,默认asc
column2 [asc|desc],] | [express]) --基表中的列名,一个索引最多有16列,long列、long raw列不能建索引列
[initrans n] --指定事务的初始入口处
[maxtrans n] --指定最大事务入口数
[tablespace tablespace_name] --指定索引所在的表空间
[pctfree n1] --指定索引在数据块中空闲空间
[storage (initial n2)] --存储参数,同create table 中的storage
[nologging] --表示创建和重建索引时允许对表做DML操作,默认情况下不应该使用
[nosort]; --表示创建索引时不进行排序,默认不适用,如果数据已经是按照该索引顺序排列的可以使用
② 修改索引
--重命名索引
alter index index_id rename to bitmap_index;
--合并索引(表使用一段时间后在索引中会产生碎片,此时索引效率会降低,可以选择重建索引或者合并索引,合并索引方式更好些,无需额外存储空间,代价较低)
alter index index_id coalesce;
--重建索引:删除原来的索引,重新建立索引
alter index index_id rebuild;
③ 删除索引
drop index index_id;
④ 查看索引
select index_name, index_type, tablespace_name, uniqueness from all_indexes where table_name ='tablename';
4. 索引分类
4.1 B树索引
默认索引,讲过排序的索引列和对应的rowid值
① 说明
▶ Oracle中最常用的索引,B树索引就是一棵二叉树;叶子节点(双向链表)包含索引列和指向表中每个匹配行的rowID值;
▶ 所有叶子节点具有相同的深度,因而不管查询条件如何,查询速度基本相同;
▶ 能够适应精确查询,模糊查询和比较查询。
② 分类
unique、non_unique(默认)、reverse key(数据列中的数据是反向存储的)
③ 创建例子
create index index_name on student('name');
④ 适用场景
列基数(列不重复个数)大时,适合适用B树索引。
4.2 位图索引
① 说明
创建位图索引时,Oracle会扫描整张表,并为索引列的每个取值建立一个位图(位图中,对表中每一行使用一位(bit、0或1)来标识该行是否包含该位图的索引列的取值,如果为1,表示对应的rowID所在记录包含改位图索引列值),最后通过位图索引中的映射函数完成位到行的rowID转换。
② 使用场景
对于基数小的列适合做位图索引(如性别)。
4.3 单列索引和复合索引
如果索引建立在多个列上,只有它的第一格列被where条件使用时,优化器才会使用该索引,即至少要包含组合索引的第一列。
4.4 函数索引
① 说明
▶ 经常要访问一些函数或者表达式时,可以将其存储在索引中,这样下次访问时,该值已经计算出来了,可以加快查询速度。
▶ 函数索引既可以使用B数索引,也可以使用位图索引;当函数结果不确定时采用B树索引,结果是固定的某几个值时使用位图索引。
▶ 函数索引中可以水泥用len、trim、substr、upper(每行返回独立结果),不能使用如sum、max、min、avg等。
② 例子
5. 索引建立原则
① 如果有两个或者以上的索引,其中有一个唯一性索引,二其他是非唯一,这种情况下,Oracle将使用唯一性索引而玩去忽略非唯一性索引。
② 至少要包含组合索引的第一列(即如果索引建立在多个列上,只有它的第一个列被where子句引用时,优化器才会使用该索引)。
③ 小表不要简历索引。
④ 对于基数大的列适合建立B树索引,对于基数小的列适合简历位图索引。
⑤ 列中有很多空值,但经常查询该列上非空记录时应该建立索引。
⑥ 经常进行连接查询的列应该创建索引。
⑦ 使用create index时要将最常查询的列放在最前面
⑧ LONG(可变长字符串数据,最长2G)和LONG RAW(可变长二进制数据,最长2G)列不能创建索引
⑨ 限制表中索引的数量(创建索引耗费时间,并且随数据量的增大而增大;索引会占用物理空间;当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度)
6. 注意事项
① 通配符在搜索词首出现时,oracle不能使用索引
--我们在name上创建索引;
create index index_name on student('name');
--下面的方式oracle不适用name索引
select * from student where name like '%wish%';
--如果通配符出现在字符串的其他位置时,优化器能够利用索引;如下:
select * from student where name like 'wish%';
② 不要在索引列上使用not,可以采用其他方式代替如下:(oracle碰到not会停止使用索引,而采用全表扫描)
select * from student where not (score=100);
select * from student where score <> 100;
--替换为
select * from student where score>100 or score <100
③ 索引上使用空值比较将停止使用索引
select * from student where score is not null;