ORACLE索引总结

 

一. B 树索引
0.      B树索引中不存在 非唯一的条目。
1)        在非唯一索引中,ORACLE会把rowid作为一个额外的列追加到键上,使得键唯一。Exp:create index I on T( x , y ) ,从概念上讲就是Create unique index I on T(x , y , rowid)。ORACLE会首先按索引键值排序,然后再按照rowid升序排序。
2)        在唯一索引中,数据只按索引键值排序。

1. 大多数情况下,B树 索引的高度都是2或者3,所以一般情况下,在索引中找到一个键只需要2或3次I/O。

2. B树索引所有叶子块都应该在同一层上,并且叶子节点实际上都是 双向链表,这样在进行索引区间扫描(index range scan)的时候,只需通过叶子节点的向前或者向后就可以了,无需再对索引结构进行导航。

3. 适当对B树索引存在重复值的列进行 压缩, 可以增加缓存命中率,使I/O数减少,因为
相关的条目可能都存在在一个块中。(Exp:create index I on T(userid , username) username=’steven’这个值可能就会对应于多个rowid放在同一个索引块中);但是带来的负面作用是使索引结构复杂化,维护索引更耗时,查询索引占用CPU更多的时间。(压缩适合用于多列索引中)

4. B树索引的 反向键索引主要用于缓解索引右侧缓冲区忙等待。适合用于类似于sequence产生的PK主键上,因为这些列不太会需要使用区间扫描,也就是不会用到max(PK),min(PK),between and或者where PK < 200等查询

5. 如果在查询中会有order by colum1 asc,column2 desc, 试着在创建索引时create index I on T(colum1 asc,column2 desc) , 因为ORACLE INDEX默认是DESC排序,在 索引中排序总比在磁盘中排序好得多。

6.  适合 B 树索引使用的 2 种情况
1)        访问表中占很小比例的行
2)        根本不访问表,所需查询的数据全部在索引中
3)        一种特殊的用法,使用索引访问表的全部行,这样的做法是为了使查询最初的响应时间很短,不是针对总吞吐量进行的优化。

7. 索引是按索引键顺序存储,索引会按键的有序顺序进行访问。索引指向的块则随机存储在堆中。

8. 建议:在thin表中使用B树索引查询<2-3%的列,fat表中<20-25%的列。
 
二.函数索引
1. 函数索引的好处: Exp: function(column1) 如果表中有1000行,即便column1列上建有索引,索引在此时也不被使用,function会执行1000次。
 
2. 建立函数索引会使插入/更新性能稍有下降,但是查询速度有了极大的提高。另外如果更新的时候没有涉及到建立函数索引的这个列,那就不会产生额外的开销。
 
3.    部分行建立索引:
1)        某一列只有很少的基数,例如只有Y和N
2)        通常只会查询where column1 = ‘N’
3)        并且值为N的行占很小的比例
4)        在此列上建立索引,由于很大的一部分索引空间是浪费的(等于Y的),不会使用到的,所以我们可以在值为’N’的那些行上面建立索引。
5)        Create index I on T(decode(column1 , ‘N’, ‘N’))
6)        利用的是B树索引特性,如果列值为null,在索引中就没有相应的条目。
 
4.    使用函数索引来保证复杂的约束:(某个条件成立时,X,Y,Z必须唯一)
1)        如果项目表,项目有2种状态,ACTIVE和INACTIVE
2)        希望ACTIVE的项目必须有唯一的项目名,INACTIVE的项目没有此要求
3)        此时项目状态这列上我们不适合建立唯一键
4)        但是我们可以建立一个唯一索引
5)        Create unique index I on T(decode(STATUS , ‘ACTIVE’ , NAME))
6)        利用的还是B树索引特性,如果列值为null,在索引中就没有相应的条目。
 
三. 索引的一些常见问题
1.B树索引特性,如果列值为null,在索引中就没有相应的条目。
1)        Create table T (x int , y int)
2)        Create unique index I T(x , y)
3)        Insert into T values(1 , 1)
4)        Insert into T values(null , 1)
5)        Insert into T values(1 , null)
6)        Insert into T values(null , null)
7)        此时索引中只有三行.(null , null)不在索引行中
8)        Insert into T values(null , null) --成功插入
9)        Insert into T values(1 , null)     --报错,违反index唯一性
10)     所以我们可以看到ORACLE中null <> null (null代表N/A)
11)     Where x is null    --这个查询无法使用索引,因为(null,null)不在索引中,如果ORACLE使用索引就会得到错误的答案
12)     同样能够得出结论,如果在一个允许null的列上面建立索引,x is null也不会使用索引
13)     可以使用索引的条件Create table T (x int , y int not null);
 
2.         外键建立索引是需要的
 
3.         索引跳跃式扫描
1)        Create index I T(x , y)
2)        Select * from T where x=5; --此时优化器可能不会使用索引
3)        Select x , y from T where x=5;       --可能使用索引,因为所需要的内容都在索引中
4)        索引跳跃式扫描—skip scan
5)        如果y只有2个基数,Y和N ,oracle会采用index
6)        Select * from T where x=5;    --会经过如下处理
7)        Select * from T where x=5 and y=’Y’
8)        Union all
9)        Select * from T where x=5 and y=’N’;
 
4.         如果索引建立在一个允许null的列上面, select * from T就会使用全表扫描,不使用索引,因为null的行并不在索引行中,所以不会使用index统计数目。
 
5.         select * from T where x=5 等价于select * from T where to_number(x)=’5’,由于存在隐式转换,所以x上的索引不会得到使用
 
6.         where trunc(date) = trunk(sysdate) 可以转换成 date >=trunc(sysdate) and date<trunk(sysdate+1)
 
7.         定期分析表
如果发现 Oracle 在有索引的情况下,没有使用索引,这并不是 Oracle 的优化器出错。在有些情况下, Oracle 确实会选择全表扫描( Full Table Scan , 而非索引扫描( Index Scan )。这些情况通常可能是:
   1. 表未做 statistics, 或者 statistics 陈旧,导致 Oracle 判断失误。
    最常见的例子,是以下这句 sql 语句:
    select count(*) from T;
  在未作 statistics 之前,它使用全表扫描,需要读取 6000 多个数据块(一个数据块是 8k , 做了 statistics 之后,使用的是 INDEX (FAST FULL SCAN) ,只需要读取 450 个数据块。但是, statistics 做得不好,也会导致 Oracle 不使用索引。
 
8.         有些情况下单列索引不如复合索引有效率!
甲、   有一种情况是显而易见的,那就是,当 sql 语句所查询的列,全部都出现在复合索引中时,此时由于 Oracle 只需要查询索引块即可获得所有数据,当然比使用多个单列索引要快得多。(此时,这种优化方式被称为 Index only access path )。需要注意的是: where 子句中的这个字段,必须是复合索引的第一个字段
乙、   还有一种情况就是 where coid>=130000 and issuedate >= to_date ('2001-07-20', 'yyyy-mm-dd') 此时复合索引 I_mytabs_test ( coid, issuedate) 的效果远远好于两个单列索引: I_mytabs1(coid), I_mytabs2(issuedate)
<think>嗯,用户让我介绍一下Oracle中的索引总结。首先,我需要回忆一下Oracle数据库索引的相关知识,确保信息准确。索引在数据库中非常重要,能显著提高查询速度,但不同类型的索引适用场景不同,这点需要详细说明。 用户可能想了解索引的基本概念,比如B树索引、位图索引、函数索引等。我应该先介绍每种索引的结构和原理,然后说明它们的优缺点以及适用情况。比如,B树索引适合高基数列,而位图索引适合低基数列,像性别这样的字段。 还要注意索引的创建和管理,比如如何创建、维护,以及索引的存储参数。用户可能关心如何选择合适的索引策略,所以需要给出一些实际例子,比如在OLTP和OLAP环境中的不同选择。 另外,索引的维护也是重点,比如重建索引、监控索引使用情况。这部分用户可能容易忽略,但实际应用中很重要,避免索引过多导致性能下降。 可能需要提到组合索引的使用技巧,比如最左前缀原则,以及索引覆盖查询的优势。还有函数索引的使用场景,比如对字段进行函数操作后的查询优化。 用户可能有疑问为什么有时候索引不生效,可以简要说明索引失效的常见原因,比如隐式类型转换、使用函数导致索引无效等。 最后,总结一下如何根据实际业务需求选择合适的索引类型,并给出一些最佳实践,比如定期分析索引使用情况,删除无用索引等。确保回答结构清晰,分点说明,方便用户理解。</think>好的,我来总结一下 Oracle 数据库中的索引核心知识点,分以下几个部分: --- ### 一、索引基础概念 **作用**:加速数据检索的数据库对象(类似书籍目录) **代价**:占用存储空间,降低DML操作速度(需维护索引结构) --- ### 二、常用索引类型 #### 1. B-Tree 索引(平衡树索引) - **结构**:根节点 → 分支节点 → 叶子节点(存储ROWID和键值) - **特点**: - 适合高基数(唯一值多)的列 - 支持精确查找和范围查询 - **语法**: ```sql CREATE INDEX idx_name ON table(column); ``` #### 2. 位图索引(Bitmap Index) - **结构**:用位图存储键值与ROWID的映射 - **特点**: - 适合低基数(重复值多)的列(如性别、状态字段) - 适合OLAP场景 - 锁粒度大,不适合高并发DML - **语法**: ```sql CREATE BITMAP INDEX idx_name ON table(column); ``` #### 3. 函数索引 - **特点**:对列应用函数后的结果建立索引 - **典型场景**:`WHERE UPPER(name) = 'JOHN'` - **语法**: ```sql CREATE INDEX idx_name ON table(UPPER(column)); ``` #### 4. 组合索引(复合索引) - **规则**: - 遵循最左前缀原则(查询必须使用最左侧列) - 列顺序影响查询效率(高频查询列放左侧) - **语法**: ```sql CREATE INDEX idx_name ON table(col1, col2); ``` --- ### 三、特殊索引类型 1. **反向键索引(Reverse Key)** - 反转键值,缓解热块争用(如序列主键的索引) - 语法:`CREATE INDEX idx_name ON table(column) REVERSE;` 2. **降序索引** - 支持`ORDER BY column DESC`优化 - 语法:`CREATE INDEX idx_name ON table(column DESC);` 3. **索引组织表(IOT)** - 表数据按索引结构存储,适用于主键频繁访问的场景 --- ### 四、索引使用策略 #### 1. 创建原则 - 在WHERE/JOIN/ORDER BY涉及的列上创建索引 - 小表(数据量 < 总行数5%)通常不需要索引 - 避免在频繁更新的列上过多建索引 #### 2. 索引失效场景 - 使用`IS NULL`/`IS NOT NULL` - 列参与函数运算(如`TO_CHAR(create_time)=...`) - 隐式类型转换(如字符串列使用数字查询) - 使用`LIKE '%value%`前导通配符 #### 3. 索引维护 - **重建索引**: ```sql ALTER INDEX idx_name REBUILD; ``` - **监控使用情况**: ```sql SELECT * FROM v$object_usage WHERE index_name = 'IDX_NAME'; ``` --- ### 五、性能优化要点 1. **索引覆盖查询**:SELECT只查询索引列时,无需回表 2. **索引跳跃扫描**(Oracle 9i+):组合索引跳过前导列查询 3. **索引压缩**:减少存储空间,语法:`CREATE INDEX ... COMPRESS` --- ### 六、实践建议 1. 定期使用`ANALYZE INDEX ... VALIDATE STRUCTURE`检查索引健康度 2. OLTP系统避免过多位图索引 3. 使用`DBMS_STATS`收集统计信息优化执行计划 需要具体案例分析或某个知识点的详细解释,可以随时告诉我! 📊
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值