oracle索引失效场景
时间: 2025-07-14 20:01:05 浏览: 3
在 Oracle 数据库中,索引是提高查询性能的重要工具,但在某些情况下,即使存在索引,优化器也可能不会使用它。以下是一些常见的导致索引失效的场景:
### 索引字段在 `WHERE` 子句中被函数处理
如果在 `WHERE` 孌中对索引列应用了函数(如 `TRUNC()`、`TO_CHAR()` 等),而没有创建基于函数的索引,则优化器通常会忽略该列上的普通索引。例如:
```sql
SELECT * FROM staff WHERE TRUNC(birthdate) = '01-MAY-82';
```
这种写法会导致索引失效[^3]。然而,可以通过改写查询以避免直接在列上使用函数来利用索引,比如:
```sql
SELECT * FROM staff WHERE birthdate < (TO_DATE('01-MAY-82') + 0.9999);
```
### 使用 `IS NULL` 或 `IS NOT NULL`
当查询条件中包含 `IS NULL` 或 `IS NOT NULL` 时,索引可能会失效。例如:
```sql
SELECT ... FROM emp WHERE colnum IS NULL;
```
这种情况下的索引效率较低,因为 B 树索引不存储 `NULL` 值,因此无法有效地通过索引来定位这些记录[^1]。
### `NOT` 操作符的使用
`NOT` 操作符(如 `!=`, `<>`, `NOT IN`, `NOT EXISTS`)通常表示“排除”逻辑,这种逻辑难以通过索引高效实现。由于索引是有序结构,它不能快速定位“不在”某个范围或集合中的数据,因此数据库优化器可能选择全表扫描而不是使用索引[^2]。
### 使用 `LIKE` 并以 `%` 开头
当 `LIKE` 表达式以通配符 `%` 开头时,索引将无法有效使用。例如:
```sql
SELECT * FROM employees WHERE name LIKE '%Smith';
```
此时数据库无法利用 `name` 字段上的索引进行快速查找[^3]。
### 联合索引未遵循最左前缀原则
对于复合索引(联合索引),只有从最左边开始连续使用的字段才能被索引支持。例如,一个 `(a, b, c)` 的联合索引可以支持 `(a)`、`(a, b)` 和 `(a, b, c)` 的查询,但不支持 `(b)`、`(c)` 或 `(b, c)` 的查询[^3]。
### 隐式类型转换或显式的类型转换
如果查询中对索引列进行了隐式或显式的类型转换,可能导致索引失效。例如,如果某列是 `VARCHAR2` 类型且有索引,而查询时传入的是数字,则数据库可能会执行隐式转换,从而跳过索引[^3]。
### 索引字段区分度差
如果某个字段的值非常集中(例如性别字段只有“男”和“女”两个值),或者大部分为 `NULL` 值,则即使建立了索引,其效率也不高,优化器可能选择不使用该索引[^3]。
### 在 `OR` 条件中混合非索引字段
当 `WHERE` 子句中包含多个条件,并通过 `OR` 连接时,如果其中一部分条件涉及未索引的列,那么整个查询可能都无法利用索引加速[^3]。
---
阅读全文
相关推荐
















