← 返回题目列表

Oracle 常见索引有哪些?B 树索引和位图索引怎么选?

高频 中等 第 3 / 32 题 更新于 2026/07/28
Oracle索引B树索引位图索引SQL优化

简化版

Oracle 最常用的是 B 树索引,适合高选择性字段、等值查询、范围查询和排序。位图索引适合低基数字段和数据仓库场景,比如性别、状态、地区等枚举值,但不适合高并发 OLTP 频繁更新表。索引选择要看查询条件、字段选择性、数据量、DML 频率和组合条件。

详细版

Oracle 常见索引包括:

  • B 树索引:默认索引,OLTP 最常用;
  • 唯一索引:保证唯一性,常配合唯一约束;
  • 组合索引:多个列共同参与过滤或排序;
  • 函数索引:对表达式或函数结果建索引;
  • 位图索引:适合低基数字段和分析查询;
  • 分区索引:配合分区表使用;
  • 反向键索引:缓解递增键插入热点。

位图索引不是“更高级的索引”,它适合读多写少的分析场景。高并发更新下,位图索引可能导致锁竞争和维护成本变高。

完整版教学

一、B 树索引是 Oracle 默认选择

创建普通索引:

CREATE INDEX idx_users_email ON users(email);

B 树索引适合:

  • 主键、唯一键;
  • 高选择性字段;
  • 等值查询;
  • 范围查询;
  • 排序和分组辅助;
  • OLTP 高频点查。

比如手机号、订单号、用户 ID、创建时间这类字段,通常优先考虑 B 树索引。

二、选择性决定索引收益

选择性可以理解为“这个条件能过滤掉多少数据”。如果字段值很分散,索引收益通常更大。

例如用户表的手机号几乎唯一:

WHERE phone = '13800000000'

索引可以快速定位少量行。

如果字段只有男女两个值:

WHERE gender = 'M'

命中数据可能占半张表。对于 OLTP 查询,普通 B 树索引未必比全表扫描更划算。

三、组合索引要匹配查询方式

组合索引:

CREATE INDEX idx_order_user_time ON orders(user_id, created_at);

适合:

WHERE user_id = :userId
  AND created_at >= :beginTime
ORDER BY created_at

组合索引不是把所有字段随便堆进去。要考虑:

  • 高频查询条件;
  • 等值列和范围列顺序;
  • 排序字段;
  • 字段选择性;
  • 索引是否过宽;
  • DML 维护成本。

四、函数索引用于表达式查询

如果 SQL 经常这样写:

WHERE UPPER(username) = 'TOM'

普通 username 索引可能无法直接发挥作用,可以考虑函数索引:

CREATE INDEX idx_users_upper_name ON users(UPPER(username));

但函数索引要求查询表达式和索引表达式能匹配,且函数结果要稳定。滥用函数索引会增加维护成本。

五、位图索引适合数据仓库

位图索引用 bitmap 表示某个值对应哪些行。它适合低基数字段,比如:

  • 性别;
  • 订单状态;
  • 是否有效;
  • 地区编码;
  • 商品类别。

在数据仓库中,经常有多个低基数字段组合过滤:

WHERE gender = 'F'
  AND status = 'ACTIVE'
  AND region = 'BJ'

位图之间可以高效做 AND、OR 运算。

但在 OLTP 高频更新表中,位图索引维护成本和锁竞争都可能很明显,所以要谨慎。

六、常见误区与追问

索引类型典型场景高风险用法
B 树索引OLTP 点查、范围、排序低选择性字段单独建索引收益低
函数索引UPPER(col)、表达式过滤SQL 表达式不匹配就用不上
位图索引数据仓库低基数字段组合过滤高频 UPDATE/DELETE 的交易表

记忆钩子:Oracle 索引不是“B 树 vs 位图谁高级”,而是“OLTP 多用 B 树,数据仓库低基数组合过滤才考虑位图”。

举个数字例子:1000 万行订单里 status 只有 5 个值,单查 status='PAID' 可能命中 300 万行,B 树索引回表成本很高;但数据仓库里同时过滤 status='PAID'region='BJ'channel='APP',多个位图可以做 AND 运算,把候选集快速缩小。若这张表每秒更新 3000 笔状态,位图索引维护和锁竞争就可能成为灾难。

  • 误区:低基数字段一定不能建索引。 OLTP 单列 B 树收益可能低,但数据仓库里的低基数字段适合位图索引组合过滤。
  • 误区:位图索引比 B 树索引更先进。 二者面向场景不同,位图索引在频繁 DML 表上代价很高。
  • 误区:函数索引建了就所有函数查询都能用。 查询表达式要和索引表达式匹配,函数结果也应稳定。
  • 追问:组合索引列顺序怎么考虑? 要结合等值条件、范围条件、排序、选择性和最常见 SQL,不是把所有字段堆进去。
  • 追问:反向键索引解决什么问题? 它可缓解递增键索引右端热点,但不适合依赖范围扫描的查询。
  • 追问:索引过多有什么代价? 每次 INSERT、UPDATE、DELETE 都要维护索引,还会占用空间和缓存,优化器选择也更复杂。

七、加强记忆

Oracle 索引选择先想 B 树:高选择性、点查、范围、排序都靠它。位图索引记住“低基数、读多写少、数据仓库”,不要放到高并发频繁更新的核心交易表上。索引不是越多越好,收益来自查询过滤,代价体现在写入维护。