Oracle建索引时那些选项怎么挑更合适一点呢?
- 问答
- 2025-12-29 23:37:33
- 2
(主要参考Oracle官方文档《SQL Tuning Guide》和《Administrator's Guide》,以及Oracle技术专家如Jonathan Lewis在《Oracle Core》等著作中的实践观点)
建索引就像给一本厚厚的书做目录,但Oracle的索引比简单的目录要灵活和强大得多,直接创建一个最基本的索引(CREATE INDEX idx_name ON table_name(column))很多时候就够用了,但如果你想让这个“目录”更贴合你的查询习惯,翻书速度更快,就需要了解下面这些选项该怎么挑。
唯一索引(UNIQUE) vs 非唯一索引(NONUNIQUE)
这个选择相对简单直接,核心判断标准就一点:你希望被索引的列(或列组合)的值在整个表里是绝对唯一的吗?
- 什么时候选UNIQUE: 当你需要强制保证数据的唯一性时,最典型的例子就是主键(Primary Key)和唯一约束(Unique Constraint),为“用户表”的“身份证号”字段建索引,由于身份证号不能重复,你就应该建一个唯一索引,这样做有两个好处:一是Oracle能利用这个索引快速检查新插入的数据是否重复;二是在某些查询中,优化器知道最多只返回一行数据,可能会选择更高效的执行路径。
- 什么时候选NONUNIQUE: 这是默认选项,也是最常见的选择,当字段值允许重复时,都用非唯一索引,为“订单表”的“客户ID”字段建索引,因为一个客户可以有多个订单,所以应该用非唯一索引。
简单说:要管住数据不重复,就用UNIQUE;否则,用默认的NONUNIQUE就行。
反向键索引(REVERSE)
这个选项听起来有点怪,它是把索引列的值的字节顺序给反转了再存储,比如数字1234,存成4321。
- 什么时候可能有用: 主要针对一类特殊问题——“右倾热点块”,想象一下,你有一张表,主键是序列号(1,2,3...),这类数据总是递增的,那么所有新插入的数据的索引条目,都会拼命往索引树最右边的叶子块上挤,导致这个块成为热点,并发插入时大家要排队,如果用了REVERSE,1234、1235、1236这三个连续的值,反转后变成4321、5321、6321,它们会被打散到索引树的不同位置,从而减轻热点块的压力。
- 什么时候千万别用: 反向键索引有个致命缺点:它几乎只能用于精确匹配(=)的查询,而完全丧失了范围查询(BETWEEN, >, <)的能力。 因为值被反转后,原本相邻的数据不再相邻,无法进行有效的范围扫描,除非你确认存在上述的热点块问题,并且你的查询从来不根据这个索引做范围查找,否则不要轻易使用它。
压缩索引(COMPRESS)
这个选项很好理解,就是对索引进行压缩,减少它占用的存储空间。
- 什么时候选COMPRESS: 当你的索引列有很多重复的前缀值时,这种情况在复合索引(多个列组成的索引)中尤其常见,你有一个复合索引在(省份, 城市)上,省份”列的值(如“广东省”)会在“广州市”、“深圳市”、“东莞市”这些条目中重复出现,压缩技术就是把这些重复的前缀只存一次,从而节省空间,空间变小了,同一个数据块里能放下的索引条目就更多,物理I/O(读写磁盘的次数)可能会减少,查询性能反而可能提升。
- 需要注意什么: 压缩和解压需要消耗一点点CPU资源,但这在现在的硬件条件下通常不是大问题,压缩带来的空间节省和潜在的性能提升往往是更显著的,对于前缀重复度高的复合索引,建议尝试使用COMPRESS选项,你还可以指定压缩的列数,比如
COMPRESS 2,表示压缩前两列。
并行创建索引(PARALLEL)
这个选项不是影响索引的结构,而是影响创建索引这个过程的速度。
- 什么时候用PARALLEL: 当你要在非常大的表(比如几亿行)上创建索引,并且你的数据库服务器有多个CPU核心时,使用PARALLEL选项可以让Oracle调动多个并行进程一起来建索引,就像让一队人同时给一本书做目录,而不是只让一个人干,这能极大缩短索引创建的时间,特别是在线业务高峰期后的维护窗口期非常有限的情况下。
- 需要注意什么: 并行操作会消耗更多的系统资源(CPU、内存、I/O带宽),在系统负载本来就很重的时候使用,可能会影响其他正在运行的业务,通常建议在系统空闲时段使用此选项,一旦索引创建完成,这个选项就不会再影响后续使用该索引的查询性能。它只是一个“建设期”的选项。
在线创建索引(ONLINE)
这个选项非常重要,它决定了在创建索引的过程中,原始表的数据能否被修改(增、删、改)。
- 默认情况(NONLINEINE): 如果不指定ONLINE,Oracle在构建索引的绝大部分时间里,会以一种独占的方式锁住表,不允许对表进行DML操作(INSERT/UPDATE/DELETE),这会导致业务中断。
- 什么时候必须用ONLINE: 对于7x24小时不允许停机的核心业务表,建索引时必须加上ONLINE关键字,它允许在索引创建过程中,用户依然可以正常地对表进行增删改操作,Oracle会采用一种复杂的机制(使用临时日志来同步变更)来保证最终索引和表数据的一致性。
- 权衡: ONLINE方式创建索引会比NONLINEINE方式稍微慢一点,因为它有额外的开销,但用一点点时间换取业务的不中断,在绝大多数生产环境下都是非常值得的。
总结一下怎么挑:
- 唯一性: 看业务规则,要唯一就选UNIQUE。
- 反向键: 除非遇到明显的索引热点块问题,否则不用。
- 压缩: 对于复合索引,尤其是前列重复值多的,大胆用,通常利大于弊。
- 并行: 建索引想快,且系统资源有空闲,就用。
- 在线: 只要不是可以随便停机的维护窗口,生产环境建索引都建议用ONLINE。
最后记住,索引不是越多越好,每个索引都会增加插入、更新、删除数据的开销,因为数据库要同时维护表和索引的数据,最好的方法是,根据你的核心查询语句,有针对性地创建最合适的索引。

本文由雪和泽于2025-12-29发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/70932.html
