Oracle 系列之索引(Index)

索引的意义在于类似一本书的目录,可以快速的查找到需要的内容。

一、创建语法

create or replace unique|bitmap index <schema>.<index_name> on <schema>.<table_name>
  (<column_name>|<expression> asc|desc ,
   <column_name>|<expression> asc|desc ...)
    tablespace <tablespace_name>
    storage <storage_settings>
    logging|nologging
    compute statistics
    nocompress|compress<nn>
    nosort|reverse
    partition|global partition<partition_setting> 
  • unique|bitmap : unique表示唯一值索引,bitmap表示位图索引,为空则默认为B-tree索引
  • column_name|expression asc|desc , ... :可以单列索引,也可以多列进行联合索引,当为的时候,为“基于函数的索引”
  • tablespace : 制定存放索引的表空间(当表和索引在不同的表空间的时候,效率更高)
  • storage : 可以设置表空间的存储参数
  • logging|nologging : 是否对索引产生redolog(对于大表来说,可以设置为nologging从而来减少空间占用,提高效率)
  • compute statistics : 设置为创建索引时,收集统计信息
  • nocompress|compressnn : 是否使用“键压缩”(使用键压缩可以删除一个键列中出现的重复值)
  • nosort|reverse : nosort表示与表中相同的顺序进行创建索引,reverse表示使用与表中相反的顺序进行创建索引
  • partition|nopartition|global partition : 可以在分区表上和未分区表上对创建的索引进行分区

二、索引优缺点

优点:

  1. 大大加快检索数据的速度
  2. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性
  3. 加速表与表之间的连接
  4. 查询语句汇总含有分组或者排序的语句时,速度更快
  5. 查询的过程中,使用索引,使用优化隐藏器,从而提高系统的性能

不足:

  1. 创建和维护索引,比较耗费时间,随着数据量的增大而增大
  2. 创建索引,占一定的物理空间(聚簇索引,占用空间会更大)
  3. 在对表进行增删改的时候,索引相应的也需要进行动态的更新

三、建立索引要求

可以建立的列:

  1. 经常需要搜索的列上
  2. 主键,一般建立唯一性索引,保持数据的唯一性
  3. 外键,提高表与表之间连接的速度
  4. 需要排序的列上
  5. where子句后边经常出现的字段
  6. 经常需要根据范围进行搜索的列上,比如日期

不适合的列:

  1. 很少进行搜索的列上
  2. 列取值比较少的列上
  3. blob类型的列上
  4. 修改频率比较高的列上

四、索引分类

1、B树索引

        B树索引是一组有序的条目。每个条目都包含一个搜索键值以及一个指向包含该值的表中一行的指针。服务器可以可预测和有效地攻击B树的有序结构,并且B树索引小于基础表。当一列包含大多数不同的值(索引基数很低)时,B树索引最能提高性能。它们还用于强制唯一性。

一般准则

考虑到高选择性,请评估在以下列上创建B树索引:

  • WHERE子句中频繁发生
  • 常用于联接表(包括聚合表)
  • 发生在ORDER BY子句中(索引可以促进排序)
  • 发生外键引用约束
  • 用于强制执行PRIMARY KEYUNIQUENESS约束

不应该在哪里创建B树

  • 在其域中只有几个不同的值。例如,类型列仅具有四个不同的值(ABCD)。可以说该索引具有低选择性。如果您有Oracle数据库,则这些选择性低的列是位图索引的理想选择。
  • 发生在WHERE子句中,但在MINMAX以外的函数中。

在这些情况下,索引会浪费空间并减慢加载过程。

1.1 唯一索引

        一般是主键字段,约束条件字段(where条件),基数大的字段(可分性高),order by 字段,也尽量建立索引。这样就不用进行order by 了,减少了排序的消耗。

create unique index idx_test_uid on test_uid(name) online tablespace tablespace2;

注意:online关键字,原因参考 

https://blog.csdn.net/jc_benben/article/details/86569074?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

1.2 复合索引(组合索引)

       条件定义模式固定,例如where条件中经常一起出现的字段。如果组合比较灵活,则分别建单一索引。
       复合索引要注意前缀性风险。例如复合索引ind_1(a,b,c),如果没有a字段出现,则索引失效。
       复合索引优先于单字段索引。复合索引中也要注意顺序,要按可选性高低或者条件定义的频度进行排序。例如,纳税人识别号,税务机关代码,月份。

create index idx_name on tablename(column_name1,column_name2) tablespace tablespace_name; 

注意: 其前导列一定要是使用最频繁的列。

1.3 反转键索引 (反向索引)

        当载入一些有序数据时,索引肯定会碰到与 I/O 相关的一些瓶颈。在数据载 入期间,某部分索引和磁盘肯定会比其他部分使用频繁得多。为了解决这个问题, 可以把索引表空间存放在能够把文件物理分割在多个磁盘上的磁盘体系结构上。

     为了解决这个问题,Oracle 还提供了一种反转键索引的方法。如果数据以反转键索引存储,这些数据的值就会与原先存储的数值相反。这样,数据 1234、1235 和 1236 就被存储成 4321、5321 和 6321。结果就是索引会为每次新插入 的行更新不同的索引块。

create index PK_REV_TEST on TEST(EMPNO) REVERSE;

注意:REVERSE 为反转键索引关键字,查看是否为反转键索引可使用以下语句

select TABLE_NAME,INDEX_NAME,INDEX_TYPE from user_indexes where INDEX_NAME like '%TEST%';

 INDEX_TYPE 为 NORMAL/REV 即创建成功

1.4 基于函数的索引

     某表的一列在平常SQL中该列都是放在函数里面,为了能用到索引来提高检索速度。

     例如:create index idx_fun on emp (upper(name));

建立需考虑的问题:

  1. 能限制在这个列上使用的函数吗?如果能,能限制所有在这个列上执行的所有函数吗?
  2. 是否有足够应付额外索引的存储空间?
  3. 在每列上增加的索引数量会对针对该表执行的 DML 语句的性能带来何种影响? 

基于函数的索引非常有用,但在实现时必须小心。在表上创建的索引越多,INSERT、UPDATE 和 DELETE 语句的执行就会花费越多的时间。 注意:对于优化器所使用的基于函数的索引来说,必须把初始参数 QUERY_REWRITE _ ENABLED 设定为 TRUE。 

2、位图索引

对于具有大量重复值的列。例如,大小列仅包含五个不同的值(盛大)。

当事实表中的外键约束列上存在位图索引时,Oracle星形转换算法使用位图索引将事实表连接到其维度。

位图索引中的条目由搜索键值和描述包含搜索键值的行的位图组成。映射中的每一位都对应于表中的一行,而on上的一位指示包含搜索键中值的行。核心价值。

create bitmap index sex_bitmap_index on student(sex);
  • 位图索引与B树索引不同,位图索引不存储rowid值(数据实际物理地址),也不存储键值。
  • 在特殊的列上创建位图 索引.
  • 特殊的列是指该列的基数很低的列(基数:列值的数量比列的行数来的小)。举例:性别列的取值只有2个(男女),但是性别列的行数远远大于该列的取值。
  • 基数很低的列不适合B树索引,适合位图索引,oracle建议,当一个列的所有取值数量与该列的行数比小于1%时,该列不适合建立B树索引,适合位图索引。
  • 在表中放置单独的位图索引是没有意义的,只有多个列建立位图索引,系统才能有效的利用位图索引提高查询速度.
  • 因为位图索引不能是唯一索引,也不能对其进行键压缩
  • 位图索引的作用源于与其他位图索引的结合,当位图索引的多个列进行查询时,oracle对这些上的位图索引进行布尔and和or运行,最终返回结果.

五、索引失效

以下内容来源于 https://blog.csdn.net/lklinkang/article/details/6130859

 

1、引起索引失效问题

1,<>
2,
单独的>,<,(有时会用到,有时不会)
3,like "%_" 百分号在前.
4,表没分析.
5,单独引用复合索引里非第一位置的索引列.
6,字符型字段为数字时在where条件里不添加引号.
7,对索引列进行运算.需要建立函数索引.
8,not in ,not exist.
9,当变量采用的是times变量,而表的字段采用的是date变量时.或相反情况。
10, 索引失效。
11,基于cost成本分析(oracle因为走全表成本会更小):查询小表,或者返回值大概在10%以上
12,有时都考虑到了 但就是不走索引,drop了从建试试在
13,B-tree索引 is null不会走,is not null会走,位图索引 is null,is not null   都会走
14,联合索引 is not null 只要在建立的索引列(不分先后)都会走, 
in null时   必须要和建立索引第一列一起使用,当建立索引第一位置条件是is null 时,其他建立索引的列可以是is null(但必须在所有列都满足is null的时候),或者=一个值;
当建立索引的第一位置是=一个值时,其他索引列可以是任何情况(包括is null =一个值),以上两种情况索引都会走。其他情况不会走。

2.解决方法

1. 选用适合的Oracle优化器

Oracle的优化器共有3种:

a. RULE (基于规则) b. COST (基于成本) c. CHOOSE (选择性)。

设置缺省的优化器,可以通过对init.ora文件中OPTIMIZER_MODE参数的各种声明,如RULE,COST,CHOOSE,ALL_ROWS,FIRST_ROWS 。你当然也在SQL句级或是会话(session)级对其进行覆盖。

为了使用基于成本的优化器(CBO, Cost-Based Optimizer) , 你必须经常运行analyze 命令,以增加数据库中的对象统计信息(object statistics)的准确性。

如果数据库的优化器模式设置为选择性(CHOOSE),那么实际的优化器模式将和是否运行过analyze命令有关。如果table已经被analyze过, 优化器模式将自动成为CBO , 反之,数据库将采用RULE形式的优化器。

(分析table

analyze table PROD_PARTS compute statistics;

ANALYZE TABLE PROD_PARTS COMPUTE STATISTICS FOR ALL INDEXED COLUMNS;

analyze table PROD_PARTS compute statistics for table for all indexes for all indexed columns;

)【有一次索引失效之后,请教DBA后,发现是数据统计的问题,具体的解决办法是执行以上语句】

在缺省情况下,Oracle采用CHOOSE优化器, 为了避免那些不必要的全表扫描(full table scan), 你必须尽量避免使用CHOOSE优化器,而直接采用基于规则或者基于成本的优化器。

2重建索引   alter index 索引名 rebuild 【online】

3、强制索引

给该语句加上hint后,强制其使用'RECORD_ENTITYID' 这个索引

sql语句变成这样

引用

select /*+ index(record,record_entityid) */ *

from RECORD

where entityId='24' and entityType='blog';

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值