外键是否自动创建索引?

我被告知,如果我外键两个表,SQL Server将在子表中创建类似于索引的东西。我很难相信这是真的,但找不到太多与此相关的具体信息。

我问这个问题的真正原因是,对于一个可能有15个相关表的表,我们在delete语句中遇到了一些非常慢的响应时间。我问过我们数据库的人,他说如果字段上有外键,它就像一个索引。你在这方面有什么经验?我是否应该在所有外键字段上添加索引,或者它们只是不必要的开销?

155656 次浏览

外键是一种约束,是两个表之间的关系——本质上与索引无关。

但众所周知,索引作为任何外键关系一部分的所有列非常有意义,因为通过fk关系,您经常需要查找一个相关的表,并根据单个值或一段值提取某些行。

因此,索引与FK有关的任何列是很有意义的,但FK本身不是一个索引。

看看Kimberly Tripp的优秀文章“SQL Server什么时候停止在外键列上放索引了?”

据我所知没有。外键只添加了一个约束,即子键中的值也要表示在父列中的某个位置。它没有告诉数据库子键也需要被索引,只是被约束。

不,外键字段上没有隐式索引,否则微软为什么说在外键上创建索引通常很有用。你的同事可能混淆了引用表中的外键字段和引用表中的主键——主键创建了一个隐式索引。

SQL Server自动为主键创建索引,但不为外键创建索引。为外键创建索引。这可能是值得的。

哇,答案五花八门。所以文档说:

FOREIGN KEY约束是索引的候选者,因为:

  • 对PRIMARY KEY约束的更改将使用相关表中的FOREIGN KEY约束进行检查。

  • 当在查询中通过将一个表的Foreign key约束中的列与另一个表中的主键列或唯一键列相匹配来组合来自相关表的数据时,外键列通常用于连接条件。索引允许Microsoft®SQL Server™2000快速查找外键表中的相关数据。但是,创建这个索引并不是必需的。即使表之间没有定义PRIMARY KEY或FOREIGN KEY约束,两个相关表的数据也可以组合,但是两个表之间的外键关系表明这两个表已经过优化,可以在使用键作为标准的查询中组合。

因此,很明显(尽管文档有点混乱),它实际上并没有创建索引。

严格来说,外键与索引毫无关系。但是,正如我上面的演讲者指出的,创建一个加速fk查找是有意义的。事实上,在MySQL中,如果你没有在FK声明中指定索引,引擎(InnoDB)会自动为你创建索引。

假设你有一张大桌子叫订单,一张小桌子叫客户。从订单到客户有一个外键。现在如果你删除一个客户,Sql Server必须检查是否有孤儿订单;如果存在,则会引发一个错误。

为了检查是否有订单,Sql Server必须搜索大订单表。现在如果有索引,搜索就会很快;如果没有,搜索将是缓慢的。

因此,在这种情况下,缓慢的删除可以用缺少索引来解释。特别是如果Sql Server必须在没有索引的情况下搜索15个大表。

附注:如果外键有ON DELETE CASCADE, Sql Server仍然需要搜索订单表,但随后删除引用被删除客户的任何订单。

在PostgeSql中,如果你点击\d tablename,你可以自己检查索引

您将看到,btree索引已经在具有主键和唯一约束的列上自动创建,但没有在具有外键的列上自动创建。

我认为这至少对研究生来说回答了你的问题。

外键不创建索引。只有备用键约束(UNIQUE)和主键约束才能创建索引。这在Oracle和SQL Server中是正确的。

我注意到实体框架6.1指向MSSQL自动添加索引的外键。

视情况而定。在MySQL中,如果你没有自己创建索引,就会创建索引:

MySQL要求外键列被索引;如果创建的表具有外键约束,但给定列上没有索引,则会创建索引。

来源:https://dev.mysql.com/doc/refman/8.0/en/constraint-foreign-key.html

MySQL 5.6也一样。