必须授予create any index系统权限,普通用户默认无权建索引,即使有select/update或alter权限也不行;该权限允许跨schema建索引,resource不含此权限,dba虽含但不应滥用。

必须授予 CREATE ANY INDEX 系统权限
Oracle 默认禁止用户在非自己拥有的表上建索引,哪怕该用户对那张表有 SELECT 或 UPDATE 权限也不行。唯一能绕过“所有权限制”的方式,是显式授予 CREATE ANY INDEX——这是系统级权限,不是对象权限,不绑定具体表。
常见错误现象:ORA-01031: insufficient privileges,即使已执行 GRANT SELECT ON other_schema.table TO user_a 依然报错。
- 授予命令:
GRANT CREATE ANY INDEX TO user_a; - 该权限生效后,
user_a可对任意 schema 的任意表执行CREATE INDEX idx_x ON scott.emp(sal); -
RESOURCE角色不含此权限,DBA角色虽含但不应直接授给普通用户
为什么 ALTER 权限不能替代 CREATE ANY INDEX
有人误以为只要对目标表有 ALTER 权限(比如 GRANT ALTER ON scott.emp TO user_a)就能建索引,这是错的。Oracle 把“建索引”视为独立操作,不归入 ALTER 范畴。
实际验证:授予 ALTER 后执行 CREATE INDEX,仍报 ORA-01031。
-
ALTER ANY TABLE是更宽泛的权限,允许重命名、加列、改类型等,风险远高于仅建索引 - 没有原生的“只允许建索引但不可改表结构”的权限粒度
- 函数索引或基于表达式的索引还额外要求对相关列有
SELECT权限,否则CREATE INDEX会失败
撤销权限不会删除已有索引
REVOKE CREATE ANY INDEX FROM user_a; 立即生效,但已存在的索引完全不受影响——Oracle 不做级联清理。
- 用户仍可查询、使用那些索引,只是不能再新建
- 已建在别人表上的索引也不会被自动
DROP - 若需清理,必须由 DBA 或索引所有者手动执行
DROP INDEX owner.idx_name;
真正安全的替代方案其实不存在
如果业务要求“只能给自己表建索引”,那只需确保用户是表的所有者,并授予其 CREATE ANY INDEX 即可——此时权限作用域自然受限于其 own schema。但凡涉及跨 schema 建索引,就必须接受 CREATE ANY INDEX 的全局性,或退回到由 DBA 代为执行建索引操作。
最容易被忽略的一点:索引创建语句中指定的表名,必须用完整限定名(如 scott.emp),不能只写 emp;否则 Oracle 默认查当前用户的同名表,可能建错地方。











