位图索引 位图索引主要针对大量相同值的列而创建。拿全国居民登录一第表来说,假设有四个字段:姓名、性别、年龄、和身份证号,年龄和性别两个字段会产生许多相同的值,性别只有男女两种值,年龄,1到120(假设最大年龄120岁)个值。那么不管一张表有几亿条记录,但根据性别字段来区分的话,只有两种取值(男、女)。那么位图索引就是根据字段的这个特性所建立的一种索引。 Bitmap Index 从上图,我们可以看出,一个叶子节点(用不同颜色标识)代表一个key , start rowid 和 end rowid规定这种类型的检索范围,一个叶子节点标记一个唯一的bitmap值。因为一个数值类型对应一个节点,当时行查询时,位图索引通过不同位图取值直接的位运算(与或),来获取到结果集合向量(计算出的结果)。 举例讲解: 假设存在数据表T,有两个数据列A和B,取值如下,我们看到A和B列中存在相同的数据。 对两个数据列A、B分别建立位图索引:idx_t_bita和idx_t_bitb。两个索引对应的存储逻辑结构如下: Idx_t_bita索引结构,对应的是叶子节点: Idx_t_bitb索引结构,对应的是叶子节点: 对查询“select * from t where b=1 and (a=’L’ or a=’M’)” 分析:位图索引使用方面,和B*索引有很大的不同。B*索引的使用,通常是从根节点开始,经过不断的分支节点比较到最近的符合条件叶子节点。通过叶子节点上的不断Scan操作,“扫描”出结果集合rowid。 而位图索引的工作方式截然不同。通过不同位图取值直接的位运算(与或),来获取到结果集合向量(计算出的结果)。 针对实例SQL,可以拆分成如下的操作: 1、a=’L’ or a=’M’ a=L:向量:1010 a=M:向量:0001 or操作的结果,就是两个向量的或操作:结果为1011。 2、结合b=1的向量 中间结果向量:1011 B=1:向量:1001 and操作的结果,1001。翻译过来就是第一和第四行是查询结果。 3、获取到结果rowid 目前知道了起始rowid和终止rowid,以及第一行和第四行为操作结果。可以通过试算的方法获取到结果集合rowid。 位图索引的特点: 1.Bitmap索引的存储空间节省 2.Bitmap索引创建的速度快 3.Bitmap索引允许键值为空 4.Bitmap索引对表记录的高效访问
1、权衡索引个数与DML之间关系,DML也就是插入、删除数据操作。这里需要权衡一个问题,建立索引的目的是为了提高查询效率的,但建立的索引过多,会影响插入、删除数据的速度,因为我们修改的表数据,索引也要跟着修改。这里需要权衡我们的操作是查询多还是修改多。 2、把索引与对应的表放在不同的表空间。当读取一个表时表与索引是同时进行的。如果表与索引和在一个表空间里就会产生资源竞争,放在两个表这空就可并行执行。 3、最好使用一样大小是块。 Oracle默认五块,读一次I/O,如果你定义6个块或10个块都需要读取两次I/O。最好是5的整数倍更能提高效率。 4、如果一个表很大,建立索引的时间很长,因为建立索引也会产生大量的redo信息,所以在创建索引时可以设置不产生或少产生redo信息。只要表数据存在,索引失败了大不了再建,所以可以不需要产生redo信息。 5、建索引的时候应该根据具体的业务SQL来创建,特别是where条件,还有where条件的顺序,尽量将过滤大范围的放在后面,因为SQL执行是从后往前的。
改变索引: SQL> alter index employees_last _name_idx storage(next 400K maxextents 100);
索引创建后,感觉不合理,也可以对其参数进行修改。详情查看相关文档
调整索引的空间: 新增加空间SQL> alter index orders_region_id_idx allocate extent (size 200K datafile '/disk6/index01.dbf');释放空间SQL> alter index oraers_id_idx deallocate unused;
索引在使用的过程中可能会出现空间不足或空间浪费的情况,这个时候需要新增或释放空间。上面两条命令完成新增与释放操作。关于空间的新增oracle可以自动帮助,如果了解数据库的情况下手动增加可以提高性能。
重新创建索引: 所引是由oracle自动完成,当我们对数据库频繁的操作时,索引也会跟着进行修改,当我们在数据库中删除一条记录时,对应的索引中并没有把相应的索引只是做一个删除标记,但它依然占据着空间。除非一个块中所有的标记全被删除的时,整个块的空间才会被释放。这样时间久了,索引的性能就会下降。这个时候可以重新建立一个干净的索引来提高效率。 SQL> alter index orders_region_id_idx rebuild tablespace index02;
通过上面的命令就可以重现建立一个索引,oracle重建立索引的过程: 1、锁表,锁表之后其他人就不能对表做任何操作。 2、创建新的(干净的)临时索引。 3、把老的索引删除掉 4、把新的索引重新命名为老索引的名字 5、对表进行解锁。
移动索引: 其实,我们移动索引到其它表空间也同样使用上面的命令,在指定表空间时指定不同的表空间。新的索引创建在别位置,把老的干掉,就相当于移动了。 SQL> alter index orders_region_id_idx rebuild tablespace index03;
在线重新创建索引: 上面介绍,在创建索引的时候,表是被锁定,不能被使用。对于一个大表,重新创建索引所需要的时间较长,为了满足用户对表操作的需求,就产生的这种在线重新创建索引。 SQL> alter index orders_id_idx rebuild online;
创建过程: 1、锁住表 2、创建立临时的和空的索引和IOT表用来存在on-going DML。普通表存放的键值,IOT所引表直接存放的表中数据;on-gong DML也就是用户所做的一些增删改的操作。 3、对表进行解锁 4、从老的索引创建一个新的索引。 5、IOT表里存放的是on-going DML信息,IOT表的内容与新创建的索引合并。 6、锁住表 7、再次将IOT表的内容更新到新索引中,把老的索引干掉。 8、把新的索引重新命名为老索引的名字 9、对表进行解锁
删除索引: SQL> drop index hr.departments_name_idx;
|