Oracle在哪些情况下会自动创建索引?

Posted

技术标签:

【中文标题】Oracle在哪些情况下会自动创建索引?【英文标题】:In which cases will Oracle create indexes automatically? 【发布时间】:2011-01-10 09:04:32 【问题描述】:

据我所知 (this page),Oracle 会自动为每个 UNIQUE 或 PRIMARY KEY 声明创建一个索引。这是在 Oracle 中自动创建索引的完整案例列表吗?

【问题讨论】:

【参考方案1】:

我将尝试整合给出的答案并使其成为社区 wiki。 因此,对于这种情况,Oracle 会自动创建索引:

    APC:用于主键和唯一键,除非此类索引已存在。 APC:用于 LOB 存储和 XMLType。 Gary:对于带有嵌套表的表。 Jim Hudson:用于物化视图。

【讨论】:

“LOB 存储”情况可能还会导致其他复杂数据类型的索引。虽然我没有测试过这个。我希望 Oracle Spatial、Oracle Text 等创建索引。 这是社区维基。如果你想添加任何东西,你可以编辑这个答案。【参考方案2】:

首先,当我们创建主键或唯一键时,Oracle 并不总是创建索引。如果该列上已经有索引,它将使用它来代替...

SQL> create table t23 (id number not null)
  2  /

Table created.

SQL> create index my_manual_idx on t23 ( id )
  2  /

Index created.

SQL> select index_name from user_indexes
  2  where table_name = 'T23'
  3  /

INDEX_NAME
------------------------------
MY_MANUAL_IDX

SQL> 

...注意MY_MANUAL_IDX 不是唯一索引;没关系……

SQL> alter table t23
  2      add constraint t23_pk primary key (id) using index
  3  /

Table altered.

SQL> select index_name from user_indexes
  2  where table_name = 'T23'
  3  /

INDEX_NAME
------------------------------
MY_MANUAL_IDX

SQL> drop index my_manual_idx
  2  /
drop index my_manual_idx
           *
ERROR at line 1:
ORA-02429: cannot drop index used for enforcement of unique/primary key


SQL> 

还有一种情况Oracle会自动创建索引:LOB存储....

SQL> alter table t23
  2      add txt clob
  3      lob (txt) store as basicfile t23_txt (tablespace users)
  4  /

Table altered.

SQL> select index_name from user_indexes
  2  where table_name = 'T23'
  3  /

INDEX_NAME
------------------------------
MY_MANUAL_IDX
SYS_IL0000556081C00002$$

SQL>

编辑

数据库将 XMLType 视为与其他 LOB 相同...

SQL> alter table t23
  2      add xmldoc xmltype
  3  /

Table altered.

SQL> select index_name from user_indexes
  2  where table_name = 'T23'
  3  /

INDEX_NAME
------------------------------
MY_MANUAL_IDX
SYS_IL0000556081C00002$$
SYS_IL0000556081C00004$$

SQL>    

【讨论】:

我已经有几年没有做Oracle了,但我似乎记得Oracle可以使用复合索引,如果设置为UNIQUE(或PRIMARY KEY?)的字段是第一个字段。我可能记错了,或者它可能自 8i 线以来已经改变,所以我建议测试它是否有用。 (避免有额外的索引并在写入中受到打击) 一个例子总是很容易理解。 如果你的表已经有索引但没有主键,我认为这不是一个好主意。这是你开场白中的假设。我从未见过与在创建表时创建的主键不同的情况,而且我不明白为什么应该以不同的方式完成它,即使从技术上讲你可以。唯一键是另外一回事......但实际上,它也应该在创建表时设置。因此,它上面会存在一些索引。 @tvCa - 显然您没有在数据仓库等工作环境中加载大量数据的经验。有时删除唯一约束但保留基础索引可能很有用。这需要我们在预先创建的非唯一索引上构建唯一约束。这不是常见的情况,但也不是不合理的情况。【参考方案3】:

不,我们越来越近了,但这还不是一个完整的列表。

创建物化视图时还会自动创建一个索引,因为 Oracle 在进行快速刷新时需要能够快速识别行。对于基于 rowid 的物化视图,它使用 I_SNAP$_tablename。对于主键实体化视图,它使用原始 PK 名称,并根据需要进行修改以使其唯一。

create materialized view testmv 
refresh force with rowid
as select * from dual;

select index_name from user_indexes where table_name = 'TESTMV';

Index Name
--------------
I_SNAP$_TESTMV

【讨论】:

【参考方案4】:

另外一个,如果你创建一个带有嵌套表的表,你会得到一个自动创建的索引。一般来说,基于对象的存储可以做到这一点,因为可以创建隐藏表。

我认为基于模式的 XMLTypes 也可以。

【讨论】:

【参考方案5】:

是的,这是完整的列表。 Oracle 自动为每个 UNIQUE 或 PRIMARY KEY 声明创建一个索引。

【讨论】:

根据accepted answer,这不是完整的列表...

以上是关于Oracle在哪些情况下会自动创建索引?的主要内容,如果未能解决你的问题,请参考以下文章

Oracle创建索引SQL简单的例子,在表中的指定字段和如何使用索引呢?

mysql索引

关于Oracle中索引的使用

MySQL like 在啥情况下会走索引

来自面试官二面MySQL索引的连续灵魂拷问

Oracle Database 19c中的自动索引