b树索引应在列选择性高(重复值<5%)、频繁用于where等值/范围查询或order by、且表dml不频繁时创建;否则易导致维护开销反超收益。

Oracle索引不是加得越多越好,而是要让每条CREATE INDEX语句都对应一个明确的查询瓶颈或约束需求。
什么时候该建B树索引?看这三点就够了
B树索引是默认选择,但只在真正能用上的场景才值得建:
- 列的选择性高(比如
employee_id、email),重复值少于总行数的5%; - 该列频繁出现在
WHERE子句中,且查询模式是等值(=)、范围(BETWEEN、>)或ORDER BY; - 表不是高频DML(每秒插入/更新超百行),否则索引维护开销会反噬性能。
常见错误:给status列(只有'Y'/'N'两个值)建B树索引——不仅没加速查询,反而拖慢UPDATE,还浪费空间。
函数索引怎么写才生效?别漏掉这些条件
函数索引只在SQL里**完全匹配**索引定义的表达式时才会被使用。例如:
CREATE INDEX idx_emp_upper_name ON employees(UPPER(last_name));
下面这条SQL能走索引:
SELECT * FROM employees WHERE UPPER(last_name) = 'SMITH';
但这些不行:
-
WHERE last_name = 'smith'(没调函数) -
WHERE UPPER(last_name) LIKE 'S%'(函数+模糊匹配,Oracle 12c前不支持) -
WHERE UPPER(TRIM(last_name)) = 'SMITH'(嵌套函数,和索引定义不一致)
注意:函数索引依赖统计信息,建完必须执行DBMS_STATS.GATHER_TABLE_STATS,否则优化器可能忽略它。
位图索引为什么不能乱用?OLTP里加了就等于埋雷
位图索引适合数据仓库,但在OLTP系统中极易引发锁问题:
- 一个
UPDATE语句修改某行的gender字段,会锁定整个位图段(可能覆盖成千上万行); - 并发
UPDATE同一低基数列(如order_status)时,会直接报ORA-00060: deadlock detected; - 即使只查不改,如果表每天有上万次DML,位图索引的维护成本远超B树索引。
判断是否适合:先查SELECT COUNT(DISTINCT gender), COUNT(*) FROM employees;,若比值
联合索引的列顺序到底怎么排?左前缀不是玄学
Oracle按索引定义从左到右匹配谓词,顺序决定能否命中:
CREATE INDEX idx_dept_job ON employees(department_id, job_id);- 能用上:WHERE
department_id = 10;WHEREdepartment_id = 10 AND job_id = 'CLERK'; - 用不上:WHERE
job_id = 'CLERK'(跳过首列,无法利用B树结构); - 排序也受限制:ORDER BY
department_id, job_id可免排序,但 ORDER BYjob_id, department_id不行。
经验规则:把过滤性最强(选择性最高)的列放最左;常用于连接(JOIN)的列次之;排序列放在最后。别为了“看起来整齐”把last_name放前面、employee_id放后面——除非你从不按ID查。
最易被忽略的一点:索引本身不自动收集统计信息,建完不跑DBMS_STATS,优化器大概率继续走全表扫描。这不是配置问题,是每次手工建索引后必须补上的动作。











