在 Oracle 中,如果表有一个复合索引(Composite Index)按顺序包含字段 A、B、C,索引的使用遵循 最左前缀原则(Leftmost Prefix Rule)。以下场景中,某些查询可能无法使用索引:
1. 会使用索引的查询场景
以下查询会利用复合索引(A、B、C):
- 条件包含 A:
WHERE A = 1
- 条件包含 A 和 B:
WHERE A = 1 AND B = 2
- 条件包含 A、B 和 C:
WHERE A = 1 AND B = 2 AND C = 3
- 范围查询(但仍满足最左前缀):
WHERE A > 1 AND B = 2 -- A 是范围查询,B 是等值查询
2.不会使用索引的查询场景
以下查询 无法有效利用复合索引:
(1) 缺少最左字段A
- 仅使用 B 或 C:
WHERE B = 2 -- 无 A,无法触发索引
WHERE C = 3 -- 无 A 和 B,无法触发索引
WHERE B = 2 AND C = 3 -- 无 A,无法触发索引
(2) 跳过了中间字段B
- 仅使用 A 和 C:
WHERE A = 1 AND C = 3 -- 跳过了 B,索引仅使用到 A 列
(3) 对字段进行了函数或类型转换
- 在索引列上使用函数或表达式:
WHERE TO_CHAR(A) = '1' -- 对 A 列进行函数转换,索引失效
WHERE A + 1 = 2 -- 对 A 列进行运算,索引失效
(4) 使用OR条件
- OR 连接非索引列:
WHERE A = 1 OR C = 3 -- Oracle 可能选择全表扫描
(5) 数据分布不均衡
- 如果 A 的选择性极低(例如 A 的值只有 1 和 2),优化器可能认为全表扫描更快,从而放弃索引。
3. 验证索引是否被使用
可以通过查看执行计划确认索引是否被使用:
EXPLAIN PLAN FOR
SELECT * FROM your_table WHERE B = 2; -- 检查是否使用索引
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
如果执行计划中出现 TABLE ACCESS FULL,说明未使用索引。
4. 如何优化
- 调整查询条件:确保查询包含复合索引的最左字段(如 A)。
- 创建新索引:如果频繁查询 B 或 C,可以单独为这些字段创建索引。
- 使用索引提示(Hint):强制优化器使用索引(需谨慎):
SELECT /*+ INDEX(your_table index_name) */ * FROM your_table WHERE B = 2;
总结
查询条件 | 是否使用索引(A、B、C) |
A = 1 | |
A = 1 AND B = 2 | |
A = 1 AND B = 2 AND C = 3 | |
B = 2 | |
A = 1 AND C = 3 | (仅用到 A) |
B = 2 AND C = 3 |
关键原则:
复合索引的最左字段(A)是触发索引的“钥匙”。如果跳过 A,即使包含 B 或 C,索引也无法生效。