【Oracle】常用对象之索引

1、什么是索引?

索引,就像一本书的目录,一栋高楼楼层的指引牌,可以很清晰的定位到我们要寻找的目标。索引index,做为数据库的一种对象,主要是用来提升数据的查找效率。Oracle数据库很强大,如果自己的数据库性能较低或执行SQL语句的效率较低,最主要的原因是索引设计的不合理,或索引使用的不合理,因此设计和优化索引成为了SQL优化的重要因素。

2、索引特点与分类

索引的重要性不言而喻,它都有哪些特点呢:

  • 索引本质也是一张表,保存了主键和索引字段,并指向实体表的记录,也占用存储空间;
  • 索引并不是每个表必须有的,但在数据量较大的表中,合理的设计和使用索引可以加快数据的查找速度,减少磁盘IO,提升数据库性能;
  • 索引虽然提升了查询效率,但对于需要频繁增删改的表而言,却降低了更新数据的操作效率,因为数据库不仅要去更新数据,也要去更新索引文件的内容。

接着,了解下索引的分类,从不同角度看分类也有所不同。

列的角度:

  • 单列索引:索引建立在表的一个列上,但一个表可以有多个单列索引。
  • 组合索引:索引建在表的多个列上。

数据结构角度:

  • B树索引:用一个倒置的树状结构(平衡二叉树)来加快查询表的速度,原理是平衡树的叶子结点包含了索引列和指向实体表每一个匹配行的rowid值(行编号),由于具有相同的深度,使用该索引的查询速度是一样的,而且能够进行精确查询、模糊查询和比较查询等;它是Oracle默认的索引,适合列基数(即列不重复值的个数)大时使用。

  • 位图索引:创建位图索引bitmap时,Oracle会扫描整张表,并为索引列的每个取值建立一个位图,在位图中,对表中每一行使用一位(bit,0或者1)来标识该行是否包含该位图的索引列的取值,如果为1,表示对应的rowid所在的记录包含该位图索引列值,最后通过位图索引中的映射函数完成位到行的ROWID转换;因此,对于基数小的列适合建立位图索引(如性别),适合做and/or/in等操作,适合于数据仓库中使用。

二者比较:

  1. 相对于B树索引,位图索引占用的空间非常小,创建和使用非常快;
  2. B树索引适合键值较多的列,而位图索引不适合;
  3. B树索引由于不记录空值,当基于is null的查询时,会使用全表扫描,而对位图索引列进行is null查询时,则可以使用索引;

常规角度:

  • 普通索引:最基本的索引,无任何限制,使用create index indexName on  tableName(column1, column2 , ...)语句创建普通的组合索引。
  • 唯一索引:索引列的值必须是唯一的,且允许有空值;若为组合索引,列组合的值必须是唯一的;通常数据库会默认表的主键为唯一索引;使用create unique index indexName on  tableName(column1, column2 , ...)语句创建唯一的组合索引。
  • 位图索引:同上,使用create bitmap index indexName on  tableName(column1, column2 , ...)语句创建位图的组合索引。
  • 反向键索引、基于函数的索引:不常用,不推荐使用,不做过多说明。

3、Oracle怎么用索引?

1. 索引的基本操作:

-- 以普通索引为例:在订单表的流水号字段上建立索引index_test1
create index index_test1 on  t_order(serial);
-- 修改索引名
alter index index_test1 rename to index_test;
-- 禁用索引
alter index index_test unusable;
-- 重建索引:可以减少硬盘碎片和提高数据库系统的性能
alter index index_test rebuild;
-- 整理碎片:对索引的无用空间进行合并,减少硬盘碎片和提高数据库系统的性能
alter index index_test coalesce;
-- 删除索引
drop index index_test;

2. 盘点设计索引的原则:

不适合建立索引的情况有:

  • 索引也会存储数据,且占用存储空间,因此不能随意的在表中创建索引,尤其是在查询中很少用到的列,也不要在表中创建无用索引;
  • 索引设计的目的是加快数据的查询效率,对于基础配置表,数据量小的表,频繁进行数据更新的表等,都不适合建立索引;
  • 索引应该建在选择性高的字段上,对于大的文本字段甚至超长字段,不要建索引; 

适合建立索引的情况有:

  • 数据量多且查询效率明显慢的表,查询需求远多于增删改操作的表,都适合在适当的列位置建立索引;
  • where子句中频繁使用的列上,经常与其他表连接的表的连接字段上;
  • 尽量使用单列索引替换组合索引,或减少组合索引中字段的数量;

一言以蔽之,设计索引要慎重,每个索引都要经过仔细分析和测试才去建立,做到真正的提升查询效率!!只要索引设计合理,使用恰当就可以大幅度提升表的查询性能,关于索引优化,可以参考我的另一篇文章:https://blog.csdn.net/qq_29119581/article/details/102571250

3. 使用执行计划优化索引:

下面说明一下,怎么在PLSQL工具中查看执行计划,并优化索引:

第一步:打开PLSQL工具,在tables下面找到indexes目录,查看建立了哪些索引;

第二步:查看SQL语句详细的执行计划,tools-- expian paln ,如图所示

第三步:查看SQL语句的执行步骤,如图所示,顺序是从未级节点往根级节点看的,图中的SQL语句执行的顺序如下:

INDEX RANGE SCAN -> TABLE ACCESS BY INDEX ROWID -> SELECT STATEMENT,GOAL=ALL_ROWS

第四步:执行计划的含义,在执行计划中,我们重点关注访问表(TABLE ACCESS BY …… )的方式,常见的有三种:

  • TABLE ACCESS BY USER ROWID(通过ROWID的表存取):rowid的值是行的物理位置,通过rowid可以快速定位到目标数据上,这也是Oracle中存取单行数据最快的方法。
  • TABLE ACCESS FULL(全表扫描):Oracle读取表中全部的行,并检查每一行是否满足SQL语句中where的条件,特别注意避免这种情况。
  • TABLE ACCESS BY INDEX SCAN(索引扫描):在索引中,存储了每个索引的键值和行的rowid,所以索引扫描其实是先扫描索引得到对应的rowid,然后再通过rowid定位到具体的行。

在上图的演示中属于索引扫描,而索引扫描又分五种:

  • INDEX UNIQUE SCAN,索引唯一扫描,效率最高。
  • INDEX RANGE SCAN,索引范围扫描,效率较高。
  • INDEX FULL SCAN,索引全扫描,效率较低。
  • INDEX FAST FULL SCAN,索引快速扫描,效率一般。
  • INDEX SKIP SCAN,索引跳跃扫描,效率还行。

Object name一栏中显示了SQL语句使用的索引名,是索引优化的重要依据。

猜你喜欢

转载自blog.csdn.net/qq_29119581/article/details/111877590