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

我有一个表 A和一个表 BAB的主键 B_ID上有一个到 B的外键。

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

我是否需要在 A.B_ID上单独创建一个索引,还是应该有一个外键来提供这个索引?

77677 次浏览

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

如果删除了 B 中的行,那么肯定希望对 A.B _ ID 进行索引。否则,Oracle 将不得不在每次从 B 中删除一行时对 A 进行全表扫描,以确保没有孤立的记录(取决于 Oracle 版本,可能还有额外的锁定影响,但是在更新的 Oracle 版本中这些影响会减少)。

外键约束本身并不提供 Oracle 上的索引-必须(也应该)创建一个。

SQL Server 从未自动将索引放到外键列上——查看 Kim Tripp 的 很棒的博客文章,了解这个城市神话的背景和历史。

然而,索引外键列通常是一个好主意——所以是的,我建议确保每个 FK 列都有一个索引备份; 不一定只有一个列——也许可以在两个或三个列上创建一个索引,其中 FK 列作为第一个。取决于您的方案和数据。

更多信息: Oracle 不会自动创建索引(就像它对唯一约束所做的那样) ,因为(a)不需要强制执行约束,(b)在某些情况下不需要索引。

然而,在大多数情况下,您需要创建一个索引(实际上,在 Oracle Apex 中有一个“未索引的外键”报告)。

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

我通常选择 没有来添加索引的一个例子是,FK 指向一个“静态数据”表,该表定义了一个列的域(例如状态代码表) ,应用程序永远不会直接对父表进行更新和删除。但是,如果在列上添加索引有利于应用程序中的重要查询,那么索引仍然是一个好主意。

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

这里最突出的似乎是选择性: 如果索引中的值是高度重复的,那么删除索引(如果可能的话)并允许表扫描可能会提供更好的性能。

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

但是

有些数据库已经在外键上自动创建索引。 喷气引擎(MicrosoftAccess 文件) 火鸟 MySQL

当然

SQL Server 神使

没有

UNIQUE、 PRIMARYKEY 和 FOREIGNKEY 约束生成强制或“返回”约束的索引(有时称为支持索引)。PRIMARYKEY 约束生成唯一索引。FOREIGNKEY 约束生成非唯一索引。如果所有列都是非空的,则 UNIQUE 约束生成唯一索引; 如果一个或多个列可以为空,则 UNIQUE 约束生成非唯一索引。因此,如果一列或一组列上有 UNIQUE、 PRIMARYKEY 或 FOREIGNKEY 约束,则不需要为这些列创建索引以提高性能。