PLSQL_性能优化索引Index介绍(概念)

2014-06-01 BaoXinjian算法

1、摘要数据库


在PLSQL查询优化中,使用和接触最多的应该是索引Index这个概念,我的也以为对Index选择和优化是程式优化过程当中比较重要的概念,特别是刚开始接触PLSQL性能优化性能优化

索引的一些概念oracle

  • 一个索引能够由一个或多个列组成,
  • 对列设置索引其实就是对列的内容按必定的方式进行排序,检索数据的时候,检索排过序的数据,检索到最后一个有效数据以后就跳出检索
  • 这样就没必要进行全表扫描了,同时能够应用不少算法提升检索效率
  • 数据库多用二分法检索数据

索引的链接方式函数

  • Hash Join
  • Nested Loops
  • Merge Join

索引的分类oop

  • B-树索引
  • 反向索引
  • 降序索引
  • 位图索引
  • 函数索引
  • 创建索引后须要分析索引才能是索引生效
  • 主键和惟一性索引的区别

索引的中Hints使用性能

  • 强制索引

创建索引的代价测试

  • 基础表维护时,系统要同时维护索引,不合理的索引将严重影响系统资源,主要表如今CPU和I/O上;
  • 插入、更新、删除数据产生大量db file sequential read锁等待;

有些状况下虽然在查询栏位中定义了index,可是PLSQL并无走该栏位的索引,由于Oracle在解析计划时一种基于Role,一种是基于Cost有些状况下走Index的效率比全表扫秒更低,并非建了Index,PLSQL性能会成倍提升,更糟的状况下,建Index还会致使性能比原来无索引更糟,这里有个理解误区,因此稍微提一下 ;)优化

并且,有时候你创建的索引可能应为空间或其余缘由被失效后,因此会致使某些程式本来没有任何问题,忽然出现性能问题,并且是很是大性能问题,因此对EBS DBA也有较高的要求,能监控一些系统异常

ui

2、索引的链接方式


1. Hash Join

2. Nested Loops

3. Merge Join

具体解析

1. Hash Join

    (1).概述

        i. 读取一个表的资料,并将放置到内存中,并创建惟一关键字的位图索引

        ii. 读取另外一个表,和内存中表经过Hash算法进行比较

    (2).适用对象

        i. 大表链接小表

        ii. 两个大表

2. Nested Loops

    (1).概述

        i. 循环外表记录

        ii. 进行逐个比对和内标的链接是否符合条件

    (2).适用对象

        小表驱动大表,返回较少的结果集

3. Merge Join

    (1).概述

        i. 两个表进行table access full

        ii. 对table access full的结果进行排序

        iii. 进行merge join对排序结构进行合并

    (2).适用对象

        经过rowid访问数据

 

3、索引的分类


1. B-树索引

2. 反向索引

3. 降序索引

4. 位图索引

5. 函数索引

6. 创建索引后须要分析索引才能是索引生效

7. 主键和惟一性索引的区别

具体解析

1. B-树索引

    (1).概述

        最经常使用的索引结构,默认创建的索引就是这种结构

        适用于高基数数据列(该列的值大多不同)

    (2).创建方式

           CREATE INDEX index_name ON wip_entities (wip_entity);

2. 反向索引

    (1).概述

    (2).创建方式

3. 降序索引

    (1).概述

        适用于须要降序排列的列

    (2).创建方式

          CREATE INDEX index_name ON wip_entities (wip_entity DESC);

4. 位图索引

    (1).概述

        适用于低基数数据列(该列的值大可能是同样)

    (2).创建方式

          CREATE BITMAP INDEX index_name ON wip_entities (sex);

5. 函数索引

    (1).概述

        适用于该列须要适用函数的列

    (2).创建方式

        CREATE INDEX index_name ON wip_entities (TRUNC(creation_date));    

6. 分析索引 

    ANALYZE INDEX index_name COMPUTE STATISTICS;

7. 主键和惟一性索引的区别

    (1). 主键是约束,惟一性索引只是一个索引

    (2). 主键不能够为空,惟一性能够为空

 

四. 索引的中Hints使用 - 强制索引


1. 创建一个测试表,和测试索引

 1 CREATE TABLE dba_name (  2  3 username VARCHAR(100),  4  5 password VARCHAR(100)  6  7 ) ;  8 9 CREATE INDEX index_t ON dba_name(username) ;

2. 方法比较

(1). 未使用强制索引

      SELECT *

      FROM dba_name

      WHERE username = 'BAOXINJIAN' 

   

(2). 使用过强制索引

     SELECT /*+ index(t index_t) */

                 *

     FROM dba_name t

     WHERE username = 'BAOXINJIAN' 

    

(3). 有些状况下虽然在查询栏位中定义了index,可是PLSQL并无走该栏位的索引,由于Oracle在解析计划时一种基于Role,一种是基于Cost

有些状况下走Index的效率比全表扫秒更低,并非建了Index,PLSQL性能会成倍提升,更糟的状况下,建Index还会致使性能比原来无索引更糟,这里有个理解误区,因此稍微提一下 ;)

 

五. 索引一些规则


一、权衡索引个数与DML之间关系,DML也就是插入、删除数据操做。

     这里须要权衡一个问题,创建索引的目的是为了提升查询效率的,但创建的索引过多,会影响插入、删除数据的速度,由于咱们修改的表数据,索引也要跟着修改。这里须要权衡咱们的操做是查询多仍是修改多。

二、把索引与对应的表放在不一样的表空间。

     当读取一个表时表与索引是同时进行的。若是表与索引和在一个表空间里就会产生资源竞争,放在两个表这空就可并行执行。

三、最好使用同样大小是块。

     Oracle默认五块,读一次I/O,若是你定义6个块或10个块都须要读取两次I/O。最好是5的整数倍更能提升效率。

四、若是一个表很大,创建索引的时间很长,由于创建索引也会产生大量的redo信息,因此在建立索引时能够设置不产生或少产生redo信息。只要表数据存在,索引失败了大不了再建,因此能够不须要产生redo信息。

五、建索引的时候应该根据具体的业务SQL来建立,特别是where条件,还有where条件的顺序,尽可能将过滤大范围的放在后面,由于SQL执行是从后往前的

 

六. 索引的操做


改变索引:

SQL> alter index employees_last _name_idx storage(next 400K maxextents 100);索引建立后,感受不合理,也能够对其参数进行修改。详情查看相关文档

2. 调整索引的空间:

2.1 新增长空间

SQL> alter index orders_region_id_idx allocate extent (size 200K datafile '/disk6/index01.dbf');

2.2 释放空间

SQL> alter index oraers_id_idx deallocate unused;

索引在使用的过程当中可能会出现空间不足或空间浪费的状况,这个时候须要新增或释放空间。上面两条命令完成新增与释放操做。关于空间的新增oracle能够自动帮助,若是了解数据库的状况下手动增长能够提升性能。

3. 从新建立索引:

所引是由oracle自动完成,当咱们对数据库频繁的操做时,索引也会跟着进行修改,当咱们在数据库中删除一条记录时,对应的索引中并无把相应的索引只是作一个删除标记,但它依然占据着空间。除非一个块中全部的标记全被删除的时,整个块的空间才会被释放。这样时间久了,索引的性能就会降低。这个时候能够从新创建一个干净的索引来提升效率。

SQL> alter index orders_region_id_idx rebuild tablespace index02;经过上面的命令就能够重现创建一个索引,oracle重创建索引的过程:

一、锁表,锁表以后其余人就不能对表作任何操做。

二、建立新的(干净的)临时索引。

三、把老的索引删除掉

四、把新的索引从新命名为老索引的名字

五、对表进行解锁。

4. 移动所引:

其实,咱们移动索引到其它表空间也一样使用上面的命令,在指定表空间时指定不一样的表空间。新的索引建立在别位置,把老的干掉,就至关于移动了。

SQL> alter index orders_region_id_idx rebuild tablespace index03;

5. 在线从新建立索引:

上面介绍,在建立索引的时候,表是被锁定,不能被使用。对于一个大表,从新建立索引所须要的时间较长,为了知足用户对表操做的需求,就产生的这种在线从新建立索引。

SQL> alter index orders_id_idx  rebuild  online;建立过程:

一、锁住表

二、建立立临时的和空的索引和IOT表用来存在on-going DML。普通表存放的键值,IOT所引表直接存放的表中数据;on-gong DML也就是用户所作的一些增删改的操做。

三、对表进行解锁

四、从老的索引建立一个新的索引。

五、IOT表里存放的是on-going DML信息,IOT表的内容与新建立的索引合并。

六、锁住表

七、再次将IOT表的内容更新到新索引中,把老的索引干掉。

八、把新的索引从新命名为老索引的名字

九、对表进行解锁

6. 整合索引碎片:

如上图,在不少索引中有剩余的空间,能够经过一个命令把剩余空间整合到一块儿。  

SQL> alter index orders_id_idx  coalesce;

7. 删除索引:

SQL> drop  index  hr.departments_name_idx;

 

七. 索引的分析


检查所引的有效果,前面介绍,索引用的时间久了会产生大量的碎片、垃圾信息与浪费的剩余空间了。能够经过从新建立索引来提升所引的性能。

能够经过一条命令来完成分析索引,分析的结果会存放在在index_stats表中。

1. 查看存放分析数据的表:

SQL> select count(*) from index_stats;

  COUNT(*)

---------- 

        0

2. 执行分析索引命令:

SQL> analyze index my_bit_idx validate structure;

Index analyzed.

再次查看 index_stats 已经有了一条数据

SQL> select count(*) from index_stats;

  COUNT(*)
----------
         1

3. 把数据查询出来:

SQL> select height,name,lf_rows,lf_blks,del_lf_rows from index_stats;

    HEIGHT   NAME              LF_ROWS   LF_BLKS   DEL_LF_ROWS
---------- ---------------------------------------------------------------------- ---------- -----------
         2   MY_BIT_IDX            1000          3            100  分析数据分析:

4. 分析

  • (HEIGHT)这个所引高度是2 ;
  • (NAME)索引名为MY_BIT_IDX ;
  • (LF_ROWS)所引表有1000行数据;
  • (LF_BLKS)占用3个块;
  • (DEL_LF_ROWS)删除100条记录’
  • 这里也验证了前面所说的一个问题,删除的100条数据只是标记为删除,由于总的数据条数依然为1000条,占用3个块,那么每一个块大于333条记录,只有删除的数据大于333条记录,这时一个块被清空,总的数据条数才会减小。

 

八. 索引的优势缺点


1. 索引的优势

 

2. 索引的缺点

 

 九. 未走索引的状况


如下是使用索引不当所引发的不走索引的几种常见状况:

1. Index on t(x,y)但where 条件中只有y字段。

一般状况会进行全表扫描。

2. select count(*) from t一般因为索引比table小,oracle会进行index full scan。

但若是索引字段含有NULL值,则不会走索引,由于索引值不包含null,若是进行index full scan统计值就不许确了。

3. select * from t where f(index_column)=value

若是不是函数索引,where条件在索引字段上进行函数操做则不走索引

4. select * from t where indexed_column=5 字段类型需转换。

例如indexed_column是字符但where条件中用了数字

5. oracle优化器认为全表扫描比走索引效率更高。

这种状况下oracle选择全表扫描。若是开发人员以为有必要走索引,可使用hint强制走索引

6. 未及时对表进行analyze,statistics不许确。

例如原先是小表,后来数据量大增。因为statistics还是旧的,oracle优化器会选择不走索引

 

********************做者: 鲍新建********************

相关文章
相关标签/搜索