我需要在Oracle的外键上创建索引吗?


120

我有一张桌子A和一张桌子BABon B的主键上有一个外键B_ID

由于某种原因(我知道有正当的理由),当我在键上连接这两个表时,它没有使用索引。

我是否需要A.B_ID在外键上单独创建索引,或者是否应该提供外键?

Answers:


136

仅外键约束不能提供Oracle的索引-必须(应该)创建一个。


11
在某些数据库上,创建外键约束还会创建索引...即Jet引擎(MSAccess文件,Firebird和MySQL)
bubi 2015年

17
如果未明确引用特定的数据库实现,则此答案毫无意义。当然,这个问题已被标记,oracle但是当您从Google搜索中找到该问题时,问题并不会立即显而易见。
developerbmw

5
我可以确认PostgreSQL-至少在撰写本文时-不会自动执行。
Dembinski

据我所知,SQL Server(2016,Azure ...)的答案相同。
Pac0

为什么必须使用Oracle在外键上创建索引?不这样做的后果是什么?
DJO丛BANG

46

创建外键不会自动在A.B_ID上创建索引。因此,从查询性能的角度来看,在A.B_ID上创建单独的索引通常是有意义的。

如果您曾经删除B中的行,则肯定要为A.B_ID编制索引。否则,每次您从B删除一行时,Oracle都必须对A进行全表扫描,以确保没有孤立的记录(根据Oracle版本的不同,可能还有其他的锁定含义,但是这些都将减少)在最新的Oracle版本中)。


1
PFK柱呢?例如,如果我有一个用于多对多关系的中间表,那么我应该为该表的两个PFK列创建索引吗?
Clamari

3
@Clamari-如果C的主键为(A_ID,B_ID),则该主键将负责从A中删除。如果您还希望能够从B中有效删除,则需要在上进行索引B_ID
贾斯汀·凯夫

25

只是为了获取更多信息:Oracle不会自动创建索引(就像对唯一约束一样),因为(a)不需要强制执行约束,并且(b)在某些情况下不需要索引。

但是,大多数时候,您将需要创建一个索引(实际上,在Oracle Apex中,有一个“未索引外键”的报告)。

每当应用程序需要能够删除父表中的行或更新PK值(这种情况比较少见)时,如果不存在索引,则DML会受到影响,因为它必须锁定整个子表。

我通常选择添加索引的情况是FK在定义列域(例如状态码表)的“静态数据”表中,而对父表的更新和删除从未完成直接由应用程序。但是,如果在列上添加索引可以使应用程序中的重要查询受益,那么索引仍然是一个好主意。


14

SQL Server从未将索引自动添加到外键列上-请查看Kim Tripp 关于该都市神话的背景和历史的精彩博客文章

通常,对您的外键列进行索引是一个好主意,因此-是的,我建议确保每个FK列均由索引进行备份;不一定只在那一列上-可能会有意义的是在两到三列上创建索引,而FK列是该列中的第一列。取决于您的方案和数据。


8

出于性能原因,应创建索引。用于主表的删除操作(以检查是否使用了要删除的记录)和通常涉及外键的联接。只有少数几张表(我没有在日志中创建它们)可能不需要索引,但是在这种情况下,您可能也不需要外键约束。

有些数据库已经自动在外键上创建索引。Jet引擎(Microsoft Access文件)Firebird MySQL

当然

SQL Server甲骨文

才不是


3
感谢提及FIrebird SQL自动执行此操作。这正是我一直在寻找的重点。
user424855'4

1

与任何与性能相关的内容一样,它取决于许多因素,并且没有灵丹妙药,例如,在非常高的活动环境中,索引的维护可能是不可接受的。

这里最明显的似乎是选择性:如果索引中的值将高度重复,则删除索引(如果可能)并允许进行表扫描可能会提供更好的性能。


1

UNIQUE,PRIMARY KEY和FOREIGN KEY约束生成强制或“约束”约束的索引(有时称为后备索引)。PRIMARY KEY约束生成唯一索引。FOREIGN KEY约束会生成非唯一索引。如果所有列都不为空,则UNIQUE约束将生成唯一索引;如果一个或多个列为可为空,则UNIQUE约束将生成非唯一索引。因此,如果一列或一组列具有UNIQUE,PRIMARY KEY或FOREIGN KEY约束,则无需在这些列上创建索引以提高性能。



链接到的文档适用于Derby(嵌入式Java数据库),而不适用于Oracle。
达沃斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.